@avtechno/sfr 1.0.18 → 2.0.1

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.
Files changed (42) hide show
  1. package/README.md +893 -45
  2. package/dist/index.mjs +20 -2
  3. package/dist/logger.mjs +9 -37
  4. package/dist/mq.mjs +46 -0
  5. package/dist/observability/index.mjs +143 -0
  6. package/dist/observability/logger.mjs +128 -0
  7. package/dist/observability/metrics.mjs +177 -0
  8. package/dist/observability/middleware/mq.mjs +156 -0
  9. package/dist/observability/middleware/rest.mjs +120 -0
  10. package/dist/observability/middleware/ws.mjs +135 -0
  11. package/dist/observability/tracer.mjs +163 -0
  12. package/dist/sfr-pipeline.mjs +412 -12
  13. package/dist/templates.mjs +8 -1
  14. package/dist/types/index.d.mts +8 -1
  15. package/dist/types/logger.d.mts +9 -3
  16. package/dist/types/mq.d.mts +19 -0
  17. package/dist/types/observability/index.d.mts +45 -0
  18. package/dist/types/observability/logger.d.mts +54 -0
  19. package/dist/types/observability/metrics.d.mts +74 -0
  20. package/dist/types/observability/middleware/mq.d.mts +46 -0
  21. package/dist/types/observability/middleware/rest.d.mts +33 -0
  22. package/dist/types/observability/middleware/ws.d.mts +35 -0
  23. package/dist/types/observability/tracer.d.mts +90 -0
  24. package/dist/types/sfr-pipeline.d.mts +42 -1
  25. package/dist/types/templates.d.mts +1 -6
  26. package/package.json +29 -4
  27. package/src/index.mts +66 -3
  28. package/src/logger.mts +16 -51
  29. package/src/mq.mts +49 -0
  30. package/src/observability/index.mts +184 -0
  31. package/src/observability/logger.mts +169 -0
  32. package/src/observability/metrics.mts +266 -0
  33. package/src/observability/middleware/mq.mts +187 -0
  34. package/src/observability/middleware/rest.mts +143 -0
  35. package/src/observability/middleware/ws.mts +162 -0
  36. package/src/observability/tracer.mts +205 -0
  37. package/src/sfr-pipeline.mts +468 -18
  38. package/src/templates.mts +14 -5
  39. package/src/types/index.d.ts +240 -16
  40. package/dist/example.mjs +0 -33
  41. package/dist/types/example.d.mts +0 -11
  42. package/src/example.mts +0 -35
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SFR Logger Module
3
+ *
4
+ * Enhanced Winston logger with automatic OpenTelemetry trace context injection.
5
+ */
6
+ import winston from "winston";
7
+ export interface LoggerConfig {
8
+ service_name?: string;
9
+ level?: string;
10
+ format?: "json" | "pretty";
11
+ transports?: winston.transport[];
12
+ }
13
+ /**
14
+ * Initializes the SFR logger with the given configuration.
15
+ * Called automatically by init_observability.
16
+ */
17
+ export declare function init_logger(config?: LoggerConfig): winston.Logger;
18
+ /**
19
+ * Gets the SFR logger instance.
20
+ * Creates a default instance if not initialized.
21
+ */
22
+ export declare function get_logger(): winston.Logger;
23
+ /**
24
+ * Creates a child logger with additional context.
25
+ * Child loggers inherit parent configuration and add their own metadata.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const route_logger = create_child_logger({
30
+ * protocol: "REST",
31
+ * route: "/api/users"
32
+ * });
33
+ * route_logger.info("Processing request");
34
+ * ```
35
+ */
36
+ export declare function create_child_logger(meta: Record<string, any>): winston.Logger;
37
+ /**
38
+ * The default SFR logger instance.
39
+ * Automatically includes trace context when available.
40
+ */
41
+ export declare const sfr_logger: {
42
+ error: (message: string, meta?: Record<string, any>) => winston.Logger;
43
+ warn: (message: string, meta?: Record<string, any>) => winston.Logger;
44
+ info: (message: string, meta?: Record<string, any>) => winston.Logger;
45
+ http: (message: string, meta?: Record<string, any>) => winston.Logger;
46
+ verbose: (message: string, meta?: Record<string, any>) => winston.Logger;
47
+ debug: (message: string, meta?: Record<string, any>) => winston.Logger;
48
+ silly: (message: string, meta?: Record<string, any>) => winston.Logger;
49
+ /**
50
+ * Creates a child logger with additional context.
51
+ */
52
+ child: (meta: Record<string, any>) => winston.Logger;
53
+ };
54
+ export { sfr_logger as logger };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * SFR Metrics Module
3
+ *
4
+ * Provides pre-defined metrics for REST, WebSocket, and MQ protocols.
5
+ */
6
+ import { type Counter, type Histogram, type UpDownCounter, type Meter } from "@opentelemetry/api";
7
+ /**
8
+ * Pre-defined SFR metrics for all protocols.
9
+ */
10
+ export interface SFRMetrics {
11
+ rest_requests_total: Counter;
12
+ rest_request_duration: Histogram;
13
+ rest_errors_total: Counter;
14
+ rest_request_size: Histogram;
15
+ rest_response_size: Histogram;
16
+ ws_connections_active: UpDownCounter;
17
+ ws_connections_total: Counter;
18
+ ws_events_total: Counter;
19
+ ws_event_duration: Histogram;
20
+ ws_errors_total: Counter;
21
+ mq_messages_received: Counter;
22
+ mq_messages_published: Counter;
23
+ mq_processing_duration: Histogram;
24
+ mq_errors_total: Counter;
25
+ mq_messages_rejected: Counter;
26
+ mq_messages_acked: Counter;
27
+ }
28
+ /**
29
+ * Gets the SFR meter instance.
30
+ */
31
+ export declare function get_meter(): Meter;
32
+ /**
33
+ * Initializes all SFR metrics.
34
+ * Called automatically by init_observability.
35
+ *
36
+ * @param service_name - Service name for metric labels
37
+ */
38
+ export declare function init_metrics(service_name: string): SFRMetrics;
39
+ /**
40
+ * Gets the SFR metrics instance.
41
+ * Initializes with default values if not already initialized.
42
+ */
43
+ export declare function get_sfr_metrics(): SFRMetrics | null;
44
+ /**
45
+ * Convenience function to record a REST request.
46
+ */
47
+ export declare function record_rest_request(attributes: {
48
+ method: string;
49
+ route: string;
50
+ status_code: number;
51
+ duration_ms: number;
52
+ request_size?: number;
53
+ response_size?: number;
54
+ }): void;
55
+ /**
56
+ * Convenience function to record a WebSocket event.
57
+ */
58
+ export declare function record_ws_event(attributes: {
59
+ namespace: string;
60
+ event: string;
61
+ duration_ms: number;
62
+ error?: boolean;
63
+ }): void;
64
+ /**
65
+ * Convenience function to record an MQ message.
66
+ */
67
+ export declare function record_mq_message(attributes: {
68
+ queue: string;
69
+ pattern: string;
70
+ duration_ms: number;
71
+ error?: boolean;
72
+ rejected?: boolean;
73
+ acked?: boolean;
74
+ }): void;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * SFR MQ Telemetry Instrumentation
3
+ *
4
+ * Instruments AMQP/RabbitMQ with tracing and metrics.
5
+ */
6
+ import type { Options } from "amqplib";
7
+ /**
8
+ * Wraps an MQ message handler with tracing and metrics.
9
+ * Extracts trace context from message headers for distributed tracing.
10
+ *
11
+ * @param queue - The queue name
12
+ * @param pattern - The communication pattern (e.g., "Point-to-Point", "Fanout")
13
+ * @param handler - The original handler function
14
+ * @returns Instrumented handler function
15
+ */
16
+ export declare function wrap_mq_handler(queue: string, pattern: string, handler: (msg: ParsedMessage) => void | Promise<void>): (msg: ParsedMessage) => Promise<void>;
17
+ /**
18
+ * Injects trace context into MQ message headers for distributed tracing.
19
+ * Call this before publishing a message to propagate the trace.
20
+ *
21
+ * @param options - The publish options object (will be modified)
22
+ * @returns The options object with trace context in headers
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const options = inject_mq_trace_context({});
27
+ * channel.publish(exchange, routingKey, content, options);
28
+ * ```
29
+ */
30
+ export declare function inject_mq_trace_context(options?: Options.Publish): Options.Publish;
31
+ /**
32
+ * Records an MQ publish event for metrics.
33
+ */
34
+ export declare function record_mq_publish(exchange: string, pattern: string): void;
35
+ /**
36
+ * Records an MQ message acknowledgment.
37
+ */
38
+ export declare function record_mq_ack(queue: string, pattern: string): void;
39
+ /**
40
+ * Records an MQ message rejection.
41
+ */
42
+ export declare function record_mq_reject(queue: string, pattern: string, requeue: boolean): void;
43
+ /**
44
+ * Extracts trace context from the current span for manual propagation.
45
+ */
46
+ export declare function get_mq_trace_headers(): Record<string, string>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * SFR REST Telemetry Middleware
3
+ *
4
+ * Express middleware that instruments REST handlers with tracing and metrics.
5
+ */
6
+ import type { Request, Response, NextFunction } from "express";
7
+ /**
8
+ * Express middleware that adds OpenTelemetry instrumentation to REST handlers.
9
+ *
10
+ * Features:
11
+ * - Creates spans for each request
12
+ * - Extracts trace context from incoming headers (distributed tracing)
13
+ * - Records request/response metrics
14
+ * - Logs HTTP traffic with trace correlation
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * app.use(sfr_rest_telemetry());
19
+ * ```
20
+ */
21
+ export declare function sfr_rest_telemetry(): (req: Request, res: Response, next: NextFunction) => void;
22
+ /**
23
+ * Extracts the SFR span from a request.
24
+ * Useful for adding custom attributes or events within handlers.
25
+ */
26
+ export declare function get_request_span(req: Request): any;
27
+ /**
28
+ * Extracts the trace context from a request.
29
+ */
30
+ export declare function get_request_trace(req: Request): {
31
+ trace_id: string;
32
+ span_id: string;
33
+ } | null;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SFR WebSocket Telemetry Instrumentation
3
+ *
4
+ * Instruments Socket.IO with tracing and metrics.
5
+ */
6
+ import type { Server, Socket } from "socket.io";
7
+ /**
8
+ * Instruments a Socket.IO server with OpenTelemetry tracing and metrics.
9
+ *
10
+ * Features:
11
+ * - Tracks active connections
12
+ * - Creates spans for each event
13
+ * - Records event metrics
14
+ * - Logs connection lifecycle with trace correlation
15
+ *
16
+ * @param io - The Socket.IO server instance
17
+ */
18
+ export declare function instrument_socket_io(io: Server): void;
19
+ /**
20
+ * Wraps a WebSocket event handler with tracing and metrics.
21
+ * Used internally by SFR to instrument registered handlers.
22
+ *
23
+ * @param namespace - The Socket.IO namespace
24
+ * @param event - The event name
25
+ * @param handler - The original handler function
26
+ * @returns Instrumented handler function
27
+ */
28
+ export declare function wrap_ws_handler(namespace: string, event: string, handler: (...args: any[]) => void | Promise<void>): (...args: any[]) => Promise<void>;
29
+ /**
30
+ * Gets the trace context attached to a socket.
31
+ */
32
+ export declare function get_socket_trace(socket: Socket): {
33
+ trace_id: string;
34
+ span_id: string;
35
+ } | null;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * SFR Tracing Module
3
+ *
4
+ * Provides utilities for creating and managing OpenTelemetry spans.
5
+ */
6
+ import { SpanKind, type Span, type Tracer, type Context } from "@opentelemetry/api";
7
+ /**
8
+ * Gets the SFR tracer instance.
9
+ */
10
+ export declare function get_tracer(): Tracer;
11
+ export interface SpanOptions {
12
+ /** Name of the span */
13
+ name: string;
14
+ /** Kind of span (default: INTERNAL) */
15
+ kind?: SpanKind;
16
+ /** Initial attributes to set on the span */
17
+ attributes?: Record<string, string | number | boolean>;
18
+ /** Parent context (optional, uses active context if not provided) */
19
+ parent_context?: Context;
20
+ }
21
+ /**
22
+ * Wraps an async function with a span for automatic tracing.
23
+ * Handles errors, sets status, and ensures span is ended.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const result = await with_span({
28
+ * name: "db:fetch_user",
29
+ * attributes: { "user.id": userId }
30
+ * }, async (span) => {
31
+ * span.setAttribute("custom.attr", "value");
32
+ * return await db.users.findById(userId);
33
+ * });
34
+ * ```
35
+ */
36
+ export declare function with_span<T>(options: SpanOptions, fn: (span: Span) => Promise<T>): Promise<T>;
37
+ /**
38
+ * Synchronous version of with_span for non-async operations.
39
+ */
40
+ export declare function with_span_sync<T>(options: SpanOptions, fn: (span: Span) => T): T;
41
+ /**
42
+ * Gets the current trace context (trace_id, span_id) if available.
43
+ * Useful for correlating logs and external systems.
44
+ */
45
+ export declare function get_trace_context(): {
46
+ trace_id: string;
47
+ span_id: string;
48
+ trace_flags: number;
49
+ } | null;
50
+ /**
51
+ * Injects the current trace context into a carrier object (e.g., HTTP headers, MQ message properties).
52
+ * Used for distributed trace propagation.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const headers = {};
57
+ * inject_trace_context(headers);
58
+ * // headers now contains traceparent, tracestate, etc.
59
+ * ```
60
+ */
61
+ export declare function inject_trace_context(carrier: Record<string, string>): void;
62
+ /**
63
+ * Extracts trace context from a carrier object and returns the context.
64
+ * Used to continue a distributed trace from an incoming request/message.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const parent_ctx = extract_trace_context(req.headers);
69
+ * await with_span({ name: "handler", parent_context: parent_ctx }, async (span) => {
70
+ * // This span is a child of the extracted context
71
+ * });
72
+ * ```
73
+ */
74
+ export declare function extract_trace_context(carrier: Record<string, string>): Context;
75
+ /**
76
+ * Adds attributes to the current active span.
77
+ * No-op if no span is active.
78
+ */
79
+ export declare function add_span_attributes(attributes: Record<string, string | number | boolean>): void;
80
+ /**
81
+ * Records an event on the current active span.
82
+ * No-op if no span is active.
83
+ */
84
+ export declare function add_span_event(name: string, attributes?: Record<string, string | number | boolean>): void;
85
+ /**
86
+ * Sets an error status on the current active span.
87
+ * No-op if no span is active.
88
+ */
89
+ export declare function set_span_error(error: Error): void;
90
+ export { SpanKind };
@@ -1,3 +1,4 @@
1
+ import { type ObservabilityOptions } from "./observability/index.mjs";
1
2
  export declare class SFRPipeline {
2
3
  private cfg;
3
4
  private oas_cfg;
@@ -14,20 +15,60 @@ export declare class SFRPipeline {
14
15
  handlers: {};
15
16
  controllers: {};
16
17
  };
18
+ ws: {
19
+ handlers: {};
20
+ controllers: {};
21
+ };
17
22
  mq: {
18
23
  handlers: {};
19
24
  controllers: {};
20
25
  };
21
26
  };
27
+ static auth_config: AuthConfig;
28
+ static rate_limit_config: RateLimitGlobalConfig;
29
+ static observability_options: ObservabilityOptions;
30
+ /**
31
+ * Sets the authentication middleware for protected routes.
32
+ * @param middleware - The authentication middleware function
33
+ */
34
+ static set_auth_middleware(middleware: AuthMiddleware): void;
35
+ /**
36
+ * Configures global rate limiting options for all routes.
37
+ * Can be overridden per-route using cfg.rate_limit in SFR files.
38
+ * @param config - Rate limit configuration options
39
+ */
40
+ static set_rate_limit_config(config: RateLimitGlobalConfig): void;
41
+ /**
42
+ * Configures observability options for tracing, metrics, and logging.
43
+ * Must be called before SFR initialization to take effect.
44
+ * @param options - Observability configuration options
45
+ */
46
+ static set_observability_options(options: ObservabilityOptions): void;
22
47
  constructor(cfg: ParserCFG, oas_cfg: OASConfig, comms: SFRProtocols);
23
48
  init(base_url?: string): Promise<ServiceDocuments>;
24
49
  private file_parsing;
25
50
  private fn_binding;
51
+ /**
52
+ * Generates OpenAPI multipart/form-data schema for Multer validators.
53
+ * Since Multer middleware functions can't be easily inspected at runtime,
54
+ * this generates a generic file upload schema.
55
+ */
56
+ private generate_multer_openapi_schema;
57
+ /**
58
+ * Gets rate limit configuration for a route, merging global defaults with route-specific config.
59
+ */
60
+ private get_rate_limit_config_for_route;
61
+ /**
62
+ * Creates a rate limiter middleware based on configuration.
63
+ * Merges route-specific config with global defaults.
64
+ */
65
+ private create_rate_limiter;
26
66
  private bind_rest_fns;
27
67
  private bind_ws_fns;
28
68
  private bind_mq_fns;
29
69
  private spec_generation;
30
70
  private generate_open_api_document;
31
- private generate_async_api_document;
71
+ private generate_ws_async_api_document;
72
+ private generate_mq_async_api_document;
32
73
  private print_to_console;
33
74
  }
@@ -1,8 +1,3 @@
1
1
  export declare function REST<V, H, C>(struct: RESTHandlerDescriptor<V, H, C>): H & C;
2
- export declare function WS<V, H, C>(struct: WSHandlerDescriptor<V, H, C>): {
3
- validators: RequestValidators;
4
- controllers: RequestControllers;
5
- handlers: WSRequestHandlers;
6
- cfg: SFRConfig;
7
- };
2
+ export declare function WS<V, H, C>(struct: WSHandlerDescriptor<V, H, C>): H & C;
8
3
  export declare function MQ<V, H, C>(struct: MQHandlerDescriptor<V, H, C>): H & C;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avtechno/sfr",
3
- "version": "1.0.18",
3
+ "version": "2.0.1",
4
4
  "description": "An opinionated way of writing services using ExpressJS.",
5
5
  "type": "module",
6
6
  "files": [
@@ -13,20 +13,35 @@
13
13
  "exports": {
14
14
  "types": "./dist/types/index.d.mts",
15
15
  "default": "./dist/index.mjs",
16
- "import": ["./dist/index.mjs", "./dist/mq.mjs"]
16
+ "import": [
17
+ "./dist/index.mjs",
18
+ "./dist/mq.mjs"
19
+ ]
17
20
  },
18
21
  "scripts": {
19
22
  "clean": "rimraf ./dist",
20
23
  "build": "yarn clean && tsc --project tsconfig.json",
21
24
  "build:watch": "yarn clean && tsc --project tsconfig.json -w",
22
- "postversion": "yarn build"
25
+ "postversion": "yarn build",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "test:coverage": "vitest run --coverage"
23
29
  },
24
30
  "prepublish": "tsc",
25
31
  "author": "Emmanuel Abellana",
26
32
  "license": "ISC",
27
33
  "dependencies": {
34
+ "@opentelemetry/api": "^1.7.0",
35
+ "@opentelemetry/auto-instrumentations-node": "^0.40.0",
36
+ "@opentelemetry/exporter-metrics-otlp-http": "^0.45.0",
37
+ "@opentelemetry/exporter-trace-otlp-http": "^0.45.0",
38
+ "@opentelemetry/resources": "^1.18.0",
39
+ "@opentelemetry/sdk-metrics": "^1.18.0",
40
+ "@opentelemetry/sdk-node": "^0.45.0",
41
+ "@opentelemetry/semantic-conventions": "^1.18.0",
28
42
  "amqplib": "^0.10.3",
29
43
  "express": "^4.18.2",
44
+ "express-rate-limit": "^7.1.5",
30
45
  "express-session": "^1.17.3",
31
46
  "file-type": "^18.5.0",
32
47
  "joi": "^17.11.0",
@@ -36,6 +51,14 @@
36
51
  "socket.io": "^4.7.2",
37
52
  "winston": "^3.17.0"
38
53
  },
54
+ "peerDependencies": {
55
+ "@opentelemetry/api": ">=1.4.0"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "@opentelemetry/api": {
59
+ "optional": true
60
+ }
61
+ },
39
62
  "devDependencies": {
40
63
  "@types/amqplib": "^0.10.3",
41
64
  "@types/express": "^4.17.19",
@@ -43,9 +66,11 @@
43
66
  "@types/js-yaml": "^4.0.7",
44
67
  "@types/multer": "^1.4.11",
45
68
  "@types/openapi-v3": "^3.0.0",
69
+ "@vitest/coverage-v8": "^2.1.9",
46
70
  "openapi-types": "^12.1.3",
47
71
  "rimraf": "^5.0.1",
48
72
  "typedoc": "^0.25.2",
49
- "typescript": "^5.2.2"
73
+ "typescript": "^5.2.2",
74
+ "vitest": "^2.1.9"
50
75
  }
51
76
  }
package/src/index.mts CHANGED
@@ -48,7 +48,8 @@ async function write_service_discovery(cfg: ParserCFG, documents: ServiceDocumen
48
48
  } break;
49
49
 
50
50
  case "WS": {
51
-
51
+ documentation = documentation as AsyncAPIDocument;
52
+ write_to_file(cfg, "ws/index.yaml", documentation);
52
53
  } break;
53
54
 
54
55
  case "MQ": {
@@ -70,7 +71,7 @@ async function write_to_file(cfg: ParserCFG, dir: string, data: object) {
70
71
  } else {//Indicates a nested file
71
72
  const file = paths.pop();//Pops the path array to be used for dir creation
72
73
  await fs.mkdir(path.join(cwd, cfg.out, ...paths), { recursive: true });
73
- fs.writeFile(path.join(cwd, cfg.out, ...paths, `${file}.yml`), yaml.dump(data), { flag: "w+" });
74
+ await fs.writeFile(path.join(cwd, cfg.out, ...paths, `${file}.yml`), yaml.dump(data), { flag: "w+" });
74
75
  }
75
76
  }
76
77
 
@@ -85,6 +86,16 @@ function inject(injections : InjectedFacilities){
85
86
  ...injections.controllers
86
87
  }
87
88
 
89
+ SFRPipeline.injections.ws.handlers = {
90
+ ...SFRPipeline.injections.ws.handlers,
91
+ ...injections.handlers
92
+ }
93
+
94
+ SFRPipeline.injections.ws.controllers = {
95
+ ...SFRPipeline.injections.ws.controllers,
96
+ ...injections.controllers
97
+ }
98
+
88
99
  SFRPipeline.injections.mq.handlers = {
89
100
  ...SFRPipeline.injections.mq.handlers,
90
101
  ...injections.handlers
@@ -96,4 +107,56 @@ function inject(injections : InjectedFacilities){
96
107
  }
97
108
  }
98
109
 
99
- export { REST, WS, MQ, MQLib, BroadcastMQ, TargetedMQ, inject };
110
+ const set_auth_middleware = SFRPipeline.set_auth_middleware.bind(SFRPipeline);
111
+ const set_rate_limit_config = SFRPipeline.set_rate_limit_config.bind(SFRPipeline);
112
+ const set_observability_options = SFRPipeline.set_observability_options.bind(SFRPipeline);
113
+
114
+ // Observability exports
115
+ export {
116
+ init_observability,
117
+ shutdown_observability,
118
+ is_observability_enabled,
119
+ type ObservabilityOptions
120
+ } from "./observability/index.mjs";
121
+
122
+ export {
123
+ get_tracer,
124
+ with_span,
125
+ with_span_sync,
126
+ get_trace_context,
127
+ inject_trace_context,
128
+ extract_trace_context,
129
+ add_span_attributes,
130
+ add_span_event,
131
+ set_span_error,
132
+ SpanKind
133
+ } from "./observability/tracer.mjs";
134
+
135
+ export {
136
+ get_sfr_metrics,
137
+ get_meter,
138
+ record_rest_request,
139
+ record_ws_event,
140
+ record_mq_message,
141
+ type SFRMetrics
142
+ } from "./observability/metrics.mjs";
143
+
144
+ export {
145
+ sfr_logger,
146
+ create_child_logger,
147
+ init_logger,
148
+ type LoggerConfig
149
+ } from "./observability/logger.mjs";
150
+
151
+ export {
152
+ REST,
153
+ WS,
154
+ MQ,
155
+ MQLib,
156
+ BroadcastMQ,
157
+ TargetedMQ,
158
+ inject,
159
+ set_auth_middleware,
160
+ set_rate_limit_config,
161
+ set_observability_options
162
+ };
package/src/logger.mts CHANGED
@@ -1,52 +1,17 @@
1
- import winston from 'winston';
1
+ /**
2
+ * SFR Logger Module (Backward Compatibility)
3
+ *
4
+ * This module re-exports the new observability logger for backward compatibility.
5
+ * New code should import from "./observability/logger.mjs" directly.
6
+ *
7
+ * @deprecated Use imports from "./observability/logger.mjs" instead
8
+ */
2
9
 
3
- // Define log levels
4
- const levels = {
5
- error: 0,
6
- warn: 1,
7
- info: 2,
8
- http: 3,
9
- verbose: 4,
10
- debug: 5,
11
- silly: 6,
12
- };
13
-
14
- // Define colors for each level
15
- const colors = {
16
- error: 'red',
17
- warn: 'yellow',
18
- info: 'green',
19
- http: 'magenta',
20
- verbose: 'cyan',
21
- debug: 'blue',
22
- silly: 'gray',
23
- };
24
-
25
- // Add colors to Winston
26
- winston.addColors(colors);
27
-
28
- // Define the format for logs
29
- const format = winston.format.combine(
30
- winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:ms' }),
31
- winston.format.colorize({ all: true }),
32
- winston.format.printf(
33
- (info) =>
34
- `${info.timestamp} ${info.level}: ${info.message}${
35
- info.metadata ? ` ${JSON.stringify(info.metadata)}` : ''
36
- }`
37
- )
38
- );
39
-
40
- // Create the Winston logger
41
- const logger = winston.createLogger({
42
- level: process.env.NODE_ENV === 'development' && Boolean(process.env.DEBUG_SFR) ? 'debug' : 'info',
43
- levels,
44
- format,
45
- transports: [
46
- // Console transport
47
- new winston.transports.Console(),
48
- ],
49
- });
50
-
51
- // Export the logger
52
- export { logger };
10
+ export {
11
+ sfr_logger as logger,
12
+ sfr_logger,
13
+ create_child_logger,
14
+ init_logger,
15
+ get_logger,
16
+ type LoggerConfig
17
+ } from "./observability/logger.mjs";