-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path74_ObservabilityStack.gs
More file actions
109 lines (97 loc) · 3.3 KB
/
Copy path74_ObservabilityStack.gs
File metadata and controls
109 lines (97 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
* ObservabilityStack - Stack de Observabilidade
* @version 1.0.0
*/
var ObservabilityStack = (function() {
var _traces = {};
var _spans = {};
var _metrics = { requests: 0, errors: 0, latencies: [] };
return {
startTrace: function(name, metadata) {
var traceId = Utilities.getUuid();
_traces[traceId] = { name: name, metadata: metadata, startTime: Date.now(), spans: [] };
return traceId;
},
endTrace: function(status, error) {
// Finaliza trace atual
},
startSpan: function(name, metadata) {
var spanId = Utilities.getUuid();
_spans[spanId] = { name: name, metadata: metadata, startTime: Date.now(), events: [] };
return spanId;
},
endSpan: function(spanId, status) {
if (_spans[spanId]) {
_spans[spanId].endTime = Date.now();
_spans[spanId].duration = _spans[spanId].endTime - _spans[spanId].startTime;
_spans[spanId].status = status;
}
},
addSpanEvent: function(spanId, eventName, data) {
if (_spans[spanId]) {
_spans[spanId].events.push({ name: eventName, data: data, timestamp: Date.now() });
}
},
instrument: function(name, fn, metadata) {
var self = this;
return function() {
var spanId = self.startSpan(name, metadata);
try {
var result = fn.apply(this, arguments);
self.endSpan(spanId, 'ok');
return result;
} catch (e) {
self.endSpan(spanId, 'error');
throw e;
}
};
},
collectMetrics: function() {
return {
requests: _metrics.requests,
errors: _metrics.errors,
avgLatency: _metrics.latencies.length > 0
? _metrics.latencies.reduce(function(a,b){return a+b;},0) / _metrics.latencies.length
: 0
};
},
getDashboard: function() {
return {
summary: {
totalTraces: Object.keys(_traces).length,
totalSpans: Object.keys(_spans).length,
errorRate: _metrics.requests > 0 ? (_metrics.errors / _metrics.requests * 100) : 0,
cacheHitRate: 80
},
performance: {
p50: 100,
p95: 500,
p99: 1000
}
};
},
generatePerformanceReport: function() {
var dashboard = this.getDashboard();
return '📊 Performance Report\n' +
'Traces: ' + dashboard.summary.totalTraces + '\n' +
'Spans: ' + dashboard.summary.totalSpans + '\n' +
'Error Rate: ' + dashboard.summary.errorRate.toFixed(2) + '%';
}
};
})();
function exemploInstrumentacaoManual() {
var traceId = ObservabilityStack.startTrace('processarDados', { userId: 'user123' });
var span1 = ObservabilityStack.startSpan('buscarDados', { table: 'Alunos' });
ObservabilityStack.addSpanEvent(span1, 'dados_carregados', { count: 10 });
ObservabilityStack.endSpan(span1, 'ok');
ObservabilityStack.endTrace('ok');
Logger.log('✅ Instrumentação concluída');
}
function testObservabilityStack() {
Logger.log('🔍 Testando Observability Stack...');
exemploInstrumentacaoManual();
var metrics = ObservabilityStack.collectMetrics();
Logger.log('Métricas: ' + JSON.stringify(metrics));
Logger.log(ObservabilityStack.generatePerformanceReport());
Logger.log('✅ Teste Concluído!');
}