@statly/observe 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -17,6 +20,155 @@ var __copyProps = (to, from, except, desc) => {
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
22
 
23
+ // src/span.ts
24
+ var Span, TraceContext;
25
+ var init_span = __esm({
26
+ "src/span.ts"() {
27
+ "use strict";
28
+ Span = class {
29
+ constructor(name, context, tags) {
30
+ this._status = "ok" /* OK */;
31
+ this._tags = {};
32
+ this._metadata = {};
33
+ this._finished = false;
34
+ this.name = name;
35
+ this.context = context;
36
+ this.startTime = Date.now();
37
+ if (tags) this._tags = { ...tags };
38
+ }
39
+ /**
40
+ * Finish the span and calculate duration
41
+ */
42
+ finish(endTime) {
43
+ if (this._finished) return;
44
+ this._endTime = endTime || Date.now();
45
+ this._durationMs = this._endTime - this.startTime;
46
+ this._finished = true;
47
+ }
48
+ setTag(key, value) {
49
+ this._tags[key] = value;
50
+ return this;
51
+ }
52
+ setMetadata(key, value) {
53
+ this._metadata[key] = value;
54
+ return this;
55
+ }
56
+ setStatus(status) {
57
+ this._status = status;
58
+ return this;
59
+ }
60
+ get status() {
61
+ return this._status;
62
+ }
63
+ get tags() {
64
+ return { ...this._tags };
65
+ }
66
+ get durationMs() {
67
+ return this._durationMs;
68
+ }
69
+ toDict() {
70
+ return {
71
+ name: this.name,
72
+ traceId: this.context.traceId,
73
+ spanId: this.context.spanId,
74
+ parentId: this.context.parentId,
75
+ startTime: this.startTime,
76
+ endTime: this._endTime,
77
+ durationMs: this._durationMs,
78
+ status: this._status,
79
+ tags: this._tags,
80
+ metadata: this._metadata
81
+ };
82
+ }
83
+ };
84
+ TraceContext = class {
85
+ static getActiveSpan() {
86
+ return this.currentSpan;
87
+ }
88
+ static setActiveSpan(span) {
89
+ this.currentSpan = span;
90
+ }
91
+ };
92
+ TraceContext.currentSpan = null;
93
+ }
94
+ });
95
+
96
+ // src/telemetry.ts
97
+ var telemetry_exports = {};
98
+ __export(telemetry_exports, {
99
+ TelemetryProvider: () => TelemetryProvider,
100
+ trace: () => trace
101
+ });
102
+ async function trace(name, operation, tags) {
103
+ const provider = TelemetryProvider.getInstance();
104
+ const span = provider.startSpan(name, tags);
105
+ try {
106
+ const result = await operation(span);
107
+ return result;
108
+ } catch (error2) {
109
+ span.setStatus("error" /* ERROR */);
110
+ span.setTag("error", "true");
111
+ if (error2 instanceof Error) {
112
+ span.setTag("exception.type", error2.name);
113
+ span.setTag("exception.message", error2.message);
114
+ }
115
+ throw error2;
116
+ } finally {
117
+ provider.finishSpan(span);
118
+ }
119
+ }
120
+ var TelemetryProvider;
121
+ var init_telemetry = __esm({
122
+ "src/telemetry.ts"() {
123
+ "use strict";
124
+ init_span();
125
+ TelemetryProvider = class _TelemetryProvider {
126
+ constructor() {
127
+ this.client = null;
128
+ }
129
+ static getInstance() {
130
+ if (!_TelemetryProvider.instance) {
131
+ _TelemetryProvider.instance = new _TelemetryProvider();
132
+ }
133
+ return _TelemetryProvider.instance;
134
+ }
135
+ setClient(client2) {
136
+ this.client = client2;
137
+ }
138
+ /**
139
+ * Start a new span
140
+ */
141
+ startSpan(name, tags) {
142
+ const parent = TraceContext.getActiveSpan();
143
+ const traceId = parent ? parent.context.traceId : this.generateId();
144
+ const parentId = parent ? parent.context.spanId : null;
145
+ const span = new Span(name, {
146
+ traceId,
147
+ spanId: this.generateId(),
148
+ parentId
149
+ }, tags);
150
+ TraceContext.setActiveSpan(span);
151
+ return span;
152
+ }
153
+ /**
154
+ * Finish and report a span
155
+ */
156
+ finishSpan(span) {
157
+ span.finish();
158
+ if (TraceContext.getActiveSpan() === span) {
159
+ TraceContext.setActiveSpan(null);
160
+ }
161
+ if (this.client) {
162
+ this.client.captureSpan(span);
163
+ }
164
+ }
165
+ generateId() {
166
+ return Math.random().toString(16).substring(2, 18);
167
+ }
168
+ };
169
+ }
170
+ });
171
+
20
172
  // src/integrations/fastify.ts
21
173
  var fastify_exports = {};
22
174
  __export(fastify_exports, {
@@ -86,10 +238,10 @@ var Transport = class {
86
238
  this.queue = [];
87
239
  try {
88
240
  await this.sendBatch(events);
89
- } catch (error) {
241
+ } catch (error2) {
90
242
  this.queue = [...events, ...this.queue].slice(0, this.maxQueueSize);
91
243
  if (this.debug) {
92
- console.error("[Statly] Failed to send events:", error);
244
+ console.error("[Statly] Failed to send events:", error2);
93
245
  }
94
246
  } finally {
95
247
  this.isSending = false;
@@ -129,13 +281,13 @@ var Transport = class {
129
281
  console.log(`[Statly] Sent ${events.length} event(s)`);
130
282
  }
131
283
  return { success: true, status: response.status };
132
- } catch (error) {
284
+ } catch (error2) {
133
285
  if (this.debug) {
134
- console.error("[Statly] Network error:", error);
286
+ console.error("[Statly] Network error:", error2);
135
287
  }
136
288
  return {
137
289
  success: false,
138
- error: error instanceof Error ? error.message : "Network error"
290
+ error: error2 instanceof Error ? error2.message : "Network error"
139
291
  };
140
292
  }
141
293
  }
@@ -202,16 +354,16 @@ var GlobalHandlers = class {
202
354
  if (!this.errorCallback) {
203
355
  return;
204
356
  }
205
- let error;
357
+ let error2;
206
358
  if (event.reason instanceof Error) {
207
- error = event.reason;
359
+ error2 = event.reason;
208
360
  } else if (typeof event.reason === "string") {
209
- error = new Error(event.reason);
361
+ error2 = new Error(event.reason);
210
362
  } else {
211
- error = new Error("Unhandled Promise Rejection");
212
- error.reason = event.reason;
363
+ error2 = new Error("Unhandled Promise Rejection");
364
+ error2.reason = event.reason;
213
365
  }
214
- this.errorCallback(error, {
366
+ this.errorCallback(error2, {
215
367
  mechanism: { type: "onunhandledrejection", handled: false }
216
368
  });
217
369
  };
@@ -254,13 +406,13 @@ var GlobalHandlers = class {
254
406
  }
255
407
  installOnError() {
256
408
  this.originalOnError = window.onerror;
257
- window.onerror = (message, source, lineno, colno, error) => {
409
+ window.onerror = (message, source, lineno, colno, error2) => {
258
410
  if (this.originalOnError) {
259
- this.originalOnError.call(window, message, source, lineno, colno, error);
411
+ this.originalOnError.call(window, message, source, lineno, colno, error2);
260
412
  }
261
413
  if (this.errorCallback) {
262
- const errorObj = error || new Error(String(message));
263
- if (!error && source) {
414
+ const errorObj = error2 || new Error(String(message));
415
+ if (!error2 && source) {
264
416
  errorObj.filename = source;
265
417
  errorObj.lineno = lineno;
266
418
  errorObj.colno = colno;
@@ -370,6 +522,7 @@ var ConsoleIntegration = class {
370
522
  };
371
523
 
372
524
  // src/client.ts
525
+ init_telemetry();
373
526
  var SDK_NAME = "@statly/observe-sdk";
374
527
  var SDK_VERSION = "0.1.0";
375
528
  var StatlyClient = class {
@@ -384,6 +537,7 @@ var StatlyClient = class {
384
537
  this.breadcrumbs = new BreadcrumbManager(this.options.maxBreadcrumbs);
385
538
  this.globalHandlers = new GlobalHandlers();
386
539
  this.consoleIntegration = new ConsoleIntegration();
540
+ TelemetryProvider.getInstance().setClient(this);
387
541
  }
388
542
  mergeOptions(options) {
389
543
  return {
@@ -423,8 +577,8 @@ var StatlyClient = class {
423
577
  }
424
578
  this.initialized = true;
425
579
  if (this.options.autoCapture) {
426
- this.globalHandlers.install((error, context) => {
427
- this.captureError(error, context);
580
+ this.globalHandlers.install((error2, context) => {
581
+ this.captureError(error2, context);
428
582
  });
429
583
  }
430
584
  if (this.options.captureConsole) {
@@ -447,15 +601,15 @@ var StatlyClient = class {
447
601
  /**
448
602
  * Capture an exception/error
449
603
  */
450
- captureException(error, context) {
604
+ captureException(error2, context) {
451
605
  let errorObj;
452
- if (error instanceof Error) {
453
- errorObj = error;
454
- } else if (typeof error === "string") {
455
- errorObj = new Error(error);
606
+ if (error2 instanceof Error) {
607
+ errorObj = error2;
608
+ } else if (typeof error2 === "string") {
609
+ errorObj = new Error(error2);
456
610
  } else {
457
611
  errorObj = new Error("Unknown error");
458
- errorObj.originalError = error;
612
+ errorObj.originalError = error2;
459
613
  }
460
614
  return this.captureError(errorObj, context);
461
615
  }
@@ -469,21 +623,45 @@ var StatlyClient = class {
469
623
  });
470
624
  return this.sendEvent(event);
471
625
  }
626
+ /**
627
+ * Capture a completed span
628
+ */
629
+ captureSpan(span) {
630
+ const event = this.buildEvent({
631
+ message: `Span: ${span.name}`,
632
+ level: "span",
633
+ span: span.toDict()
634
+ });
635
+ return this.sendEvent(event);
636
+ }
637
+ /**
638
+ * Start a new tracing span
639
+ */
640
+ startSpan(name, tags) {
641
+ return TelemetryProvider.getInstance().startSpan(name, tags);
642
+ }
643
+ /**
644
+ * Execute a function within a trace span
645
+ */
646
+ async trace(name, operation, tags) {
647
+ const { trace: traceFn } = await Promise.resolve().then(() => (init_telemetry(), telemetry_exports));
648
+ return traceFn(name, operation, tags);
649
+ }
472
650
  /**
473
651
  * Internal method to capture an error
474
652
  */
475
- captureError(error, context) {
653
+ captureError(error2, context) {
476
654
  if (Math.random() > this.options.sampleRate) {
477
655
  return "";
478
656
  }
479
657
  const event = this.buildEvent({
480
- message: error.message,
658
+ message: error2.message,
481
659
  level: "error",
482
- stack: error.stack,
660
+ stack: error2.stack,
483
661
  exception: {
484
- type: error.name,
485
- value: error.message,
486
- stacktrace: this.parseStackTrace(error.stack)
662
+ type: error2.name,
663
+ value: error2.message,
664
+ stacktrace: this.parseStackTrace(error2.stack)
487
665
  },
488
666
  extra: context
489
667
  });
@@ -677,6 +855,35 @@ var StatlyClient = class {
677
855
  }
678
856
  };
679
857
 
858
+ // src/logger/formatters/console.ts
859
+ var COLORS = {
860
+ reset: "\x1B[0m",
861
+ bold: "\x1B[1m",
862
+ dim: "\x1B[2m",
863
+ // Foreground colors
864
+ black: "\x1B[30m",
865
+ red: "\x1B[31m",
866
+ green: "\x1B[32m",
867
+ yellow: "\x1B[33m",
868
+ blue: "\x1B[34m",
869
+ magenta: "\x1B[35m",
870
+ cyan: "\x1B[36m",
871
+ white: "\x1B[37m",
872
+ gray: "\x1B[90m",
873
+ // Background colors
874
+ bgRed: "\x1B[41m",
875
+ bgYellow: "\x1B[43m"
876
+ };
877
+ var LEVEL_COLORS = {
878
+ trace: COLORS.gray,
879
+ debug: COLORS.cyan,
880
+ info: COLORS.green,
881
+ warn: COLORS.yellow,
882
+ error: COLORS.red,
883
+ fatal: `${COLORS.bgRed}${COLORS.white}`,
884
+ audit: COLORS.magenta
885
+ };
886
+
680
887
  // src/index.ts
681
888
  var client = null;
682
889
  function loadDsnFromEnv() {
@@ -711,12 +918,12 @@ function init(options) {
711
918
  client = new StatlyClient(finalOptions);
712
919
  client.init();
713
920
  }
714
- function captureException(error, context) {
921
+ function captureException(error2, context) {
715
922
  if (!client) {
716
923
  console.warn("[Statly] SDK not initialized. Call Statly.init() first.");
717
924
  return "";
718
925
  }
719
- return client.captureException(error, context);
926
+ return client.captureException(error2, context);
720
927
  }
721
928
  function captureMessage(message, level = "info") {
722
929
  if (!client) {
@@ -769,6 +976,20 @@ async function close() {
769
976
  function getClient() {
770
977
  return client;
771
978
  }
979
+ async function trace3(name, operation, tags) {
980
+ if (!client) {
981
+ return operation(null);
982
+ }
983
+ return client.trace(name, operation, tags);
984
+ }
985
+ function startSpan(name, tags) {
986
+ if (!client) return null;
987
+ return client.startSpan(name, tags);
988
+ }
989
+ function captureSpan(span) {
990
+ if (!client) return "";
991
+ return client.captureSpan(span);
992
+ }
772
993
  var Statly = {
773
994
  init,
774
995
  captureException,
@@ -779,7 +1000,10 @@ var Statly = {
779
1000
  addBreadcrumb,
780
1001
  flush,
781
1002
  close,
782
- getClient
1003
+ getClient,
1004
+ trace: trace3,
1005
+ startSpan,
1006
+ captureSpan
783
1007
  };
784
1008
 
785
1009
  // src/integrations/fastify.ts
@@ -819,16 +1043,16 @@ function statlyFastifyPlugin(fastify, options, done) {
819
1043
  });
820
1044
  hookDone();
821
1045
  });
822
- fastify.setErrorHandler((error, request, reply) => {
823
- const statusCode = error.statusCode || 500;
1046
+ fastify.setErrorHandler((error2, request, reply) => {
1047
+ const statusCode = error2.statusCode || 500;
824
1048
  if (skipStatusCodes.includes(statusCode)) {
825
- throw error;
1049
+ throw error2;
826
1050
  }
827
- if (!captureValidationErrors && error.validation) {
828
- throw error;
1051
+ if (!captureValidationErrors && error2.validation) {
1052
+ throw error2;
829
1053
  }
830
- if (shouldCapture && !shouldCapture(error)) {
831
- throw error;
1054
+ if (shouldCapture && !shouldCapture(error2)) {
1055
+ throw error2;
832
1056
  }
833
1057
  const context = {
834
1058
  request: {
@@ -841,27 +1065,27 @@ function statlyFastifyPlugin(fastify, options, done) {
841
1065
  params: request.params
842
1066
  },
843
1067
  error: {
844
- statusCode: error.statusCode,
845
- code: error.code
1068
+ statusCode: error2.statusCode,
1069
+ code: error2.code
846
1070
  }
847
1071
  };
848
1072
  if (request.ip) {
849
1073
  context.ip = request.ip;
850
1074
  }
851
- if (error.validation) {
852
- context.validation = error.validation;
1075
+ if (error2.validation) {
1076
+ context.validation = error2.validation;
853
1077
  }
854
1078
  Statly.setTag("http.method", request.method);
855
1079
  Statly.setTag("http.url", request.routerPath || request.url);
856
1080
  Statly.setTag("http.status_code", String(statusCode));
857
- Statly.captureException(error, context);
858
- throw error;
1081
+ Statly.captureException(error2, context);
1082
+ throw error2;
859
1083
  });
860
1084
  done();
861
1085
  }
862
1086
  var statlyPlugin = statlyFastifyPlugin;
863
1087
  function createRequestCapture(request) {
864
- return (error, additionalContext) => {
1088
+ return (error2, additionalContext) => {
865
1089
  const context = {
866
1090
  request: {
867
1091
  id: request.id,
@@ -871,7 +1095,7 @@ function createRequestCapture(request) {
871
1095
  },
872
1096
  ...additionalContext
873
1097
  };
874
- return Statly.captureException(error, context);
1098
+ return Statly.captureException(error2, context);
875
1099
  };
876
1100
  }
877
1101
  function sanitizeHeaders(headers) {
@@ -2,7 +2,9 @@ import {
2
2
  createRequestCapture,
3
3
  statlyFastifyPlugin,
4
4
  statlyPlugin
5
- } from "../chunk-UNDSALI5.mjs";
5
+ } from "../chunk-SJ7C46AP.mjs";
6
+ import "../chunk-7AITSJLP.mjs";
7
+ import "../chunk-J5AHUFP2.mjs";
6
8
  export {
7
9
  createRequestCapture,
8
10
  statlyFastifyPlugin,