@justanalyticsapp/node 0.1.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.
Files changed (52) hide show
  1. package/dist/client.d.ts +286 -0
  2. package/dist/client.js +681 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/context.d.ts +126 -0
  5. package/dist/context.js +170 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/errors.d.ts +135 -0
  8. package/dist/errors.js +180 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/index.d.ts +301 -0
  11. package/dist/index.js +314 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/integrations/express.d.ts +77 -0
  14. package/dist/integrations/express.js +87 -0
  15. package/dist/integrations/express.js.map +1 -0
  16. package/dist/integrations/http.d.ts +129 -0
  17. package/dist/integrations/http.js +465 -0
  18. package/dist/integrations/http.js.map +1 -0
  19. package/dist/integrations/metrics.d.ts +110 -0
  20. package/dist/integrations/metrics.js +313 -0
  21. package/dist/integrations/metrics.js.map +1 -0
  22. package/dist/integrations/next.d.ts +252 -0
  23. package/dist/integrations/next.js +480 -0
  24. package/dist/integrations/next.js.map +1 -0
  25. package/dist/integrations/pg.d.ts +169 -0
  26. package/dist/integrations/pg.js +616 -0
  27. package/dist/integrations/pg.js.map +1 -0
  28. package/dist/integrations/pino.d.ts +52 -0
  29. package/dist/integrations/pino.js +153 -0
  30. package/dist/integrations/pino.js.map +1 -0
  31. package/dist/integrations/redis.d.ts +190 -0
  32. package/dist/integrations/redis.js +597 -0
  33. package/dist/integrations/redis.js.map +1 -0
  34. package/dist/integrations/winston.d.ts +48 -0
  35. package/dist/integrations/winston.js +99 -0
  36. package/dist/integrations/winston.js.map +1 -0
  37. package/dist/logger.d.ts +148 -0
  38. package/dist/logger.js +162 -0
  39. package/dist/logger.js.map +1 -0
  40. package/dist/span.d.ts +192 -0
  41. package/dist/span.js +197 -0
  42. package/dist/span.js.map +1 -0
  43. package/dist/transport.d.ts +246 -0
  44. package/dist/transport.js +654 -0
  45. package/dist/transport.js.map +1 -0
  46. package/dist/utils/headers.d.ts +60 -0
  47. package/dist/utils/headers.js +93 -0
  48. package/dist/utils/headers.js.map +1 -0
  49. package/dist/utils/id.d.ts +23 -0
  50. package/dist/utils/id.js +36 -0
  51. package/dist/utils/id.js.map +1 -0
  52. package/package.json +65 -0
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @file packages/node-sdk/src/integrations/pino.ts
3
+ * @description Pino transport for JustAnalytics log integration.
4
+ *
5
+ * Implements Story 046 - SDK Log Integration
6
+ *
7
+ * Creates a writable stream that parses Pino's newline-delimited JSON
8
+ * output and pipes log entries through the JustAnalytics SDK logger.
9
+ *
10
+ * Usage (programmatic):
11
+ * ```typescript
12
+ * import pino from 'pino';
13
+ * import { createJustAnalyticsPinoTransport } from '@justanalyticsapp/node/pino';
14
+ *
15
+ * const logger = pino(
16
+ * { level: 'info' },
17
+ * createJustAnalyticsPinoTransport(),
18
+ * );
19
+ * ```
20
+ *
21
+ * Usage (Pino transport API):
22
+ * ```typescript
23
+ * import pino from 'pino';
24
+ *
25
+ * const logger = pino({
26
+ * transport: {
27
+ * target: '@justanalyticsapp/node/pino',
28
+ * },
29
+ * });
30
+ * ```
31
+ *
32
+ * The transport requires `pino` as a peer dependency.
33
+ */
34
+ import { Writable } from 'stream';
35
+ import type { LogLevel } from '../logger';
36
+ /** Configuration options for the Pino transport */
37
+ export interface JustAnalyticsPinoTransportOptions {
38
+ /** Custom mapping from Pino numeric levels to JA levels */
39
+ levelMap?: Record<number, LogLevel>;
40
+ }
41
+ /**
42
+ * Create a writable stream that pipes Pino log entries to JustAnalytics.
43
+ *
44
+ * The stream parses newline-delimited JSON from Pino, maps numeric levels
45
+ * to JA levels, strips Pino internal fields, and forwards log entries
46
+ * through JA.logger for batched transport with automatic trace context.
47
+ *
48
+ * @param options - Optional configuration for level mapping
49
+ * @returns A Writable stream compatible with Pino's destination API
50
+ */
51
+ export declare function createJustAnalyticsPinoTransport(options?: JustAnalyticsPinoTransportOptions): Writable;
52
+ export default createJustAnalyticsPinoTransport;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ /**
3
+ * @file packages/node-sdk/src/integrations/pino.ts
4
+ * @description Pino transport for JustAnalytics log integration.
5
+ *
6
+ * Implements Story 046 - SDK Log Integration
7
+ *
8
+ * Creates a writable stream that parses Pino's newline-delimited JSON
9
+ * output and pipes log entries through the JustAnalytics SDK logger.
10
+ *
11
+ * Usage (programmatic):
12
+ * ```typescript
13
+ * import pino from 'pino';
14
+ * import { createJustAnalyticsPinoTransport } from '@justanalyticsapp/node/pino';
15
+ *
16
+ * const logger = pino(
17
+ * { level: 'info' },
18
+ * createJustAnalyticsPinoTransport(),
19
+ * );
20
+ * ```
21
+ *
22
+ * Usage (Pino transport API):
23
+ * ```typescript
24
+ * import pino from 'pino';
25
+ *
26
+ * const logger = pino({
27
+ * transport: {
28
+ * target: '@justanalyticsapp/node/pino',
29
+ * },
30
+ * });
31
+ * ```
32
+ *
33
+ * The transport requires `pino` as a peer dependency.
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createJustAnalyticsPinoTransport = createJustAnalyticsPinoTransport;
37
+ const stream_1 = require("stream");
38
+ /** Pino numeric level to JustAnalytics level mapping */
39
+ const DEFAULT_PINO_LEVEL_MAP = {
40
+ 10: 'debug', // pino 'trace'
41
+ 20: 'debug', // pino 'debug'
42
+ 30: 'info', // pino 'info'
43
+ 40: 'warn', // pino 'warn'
44
+ 50: 'error', // pino 'error'
45
+ 60: 'fatal', // pino 'fatal'
46
+ };
47
+ /** Pino internal fields to exclude from attributes */
48
+ const PINO_INTERNAL_FIELDS = new Set(['level', 'msg', 'time', 'pid', 'hostname', 'v']);
49
+ /**
50
+ * Map a Pino numeric level to a JA LogLevel.
51
+ * Uses the exact level if found, otherwise finds the closest lower level.
52
+ * Defaults to 'info' if no match is found.
53
+ *
54
+ * @param pinoLevel - Pino numeric log level
55
+ * @param levelMap - Level mapping to use
56
+ * @returns The corresponding JA LogLevel
57
+ */
58
+ function mapPinoLevel(pinoLevel, levelMap) {
59
+ if (levelMap[pinoLevel])
60
+ return levelMap[pinoLevel];
61
+ // Find closest lower level
62
+ const levels = Object.keys(levelMap)
63
+ .map(Number)
64
+ .sort((a, b) => b - a);
65
+ for (const l of levels) {
66
+ if (l <= pinoLevel)
67
+ return levelMap[l];
68
+ }
69
+ return 'info';
70
+ }
71
+ /**
72
+ * Create a writable stream that pipes Pino log entries to JustAnalytics.
73
+ *
74
+ * The stream parses newline-delimited JSON from Pino, maps numeric levels
75
+ * to JA levels, strips Pino internal fields, and forwards log entries
76
+ * through JA.logger for batched transport with automatic trace context.
77
+ *
78
+ * @param options - Optional configuration for level mapping
79
+ * @returns A Writable stream compatible with Pino's destination API
80
+ */
81
+ function createJustAnalyticsPinoTransport(options) {
82
+ const levelMap = options?.levelMap
83
+ ? { ...DEFAULT_PINO_LEVEL_MAP, ...options.levelMap }
84
+ : { ...DEFAULT_PINO_LEVEL_MAP };
85
+ let buffer = '';
86
+ return new stream_1.Writable({
87
+ write(chunk, _encoding, callback) {
88
+ try {
89
+ buffer += chunk.toString();
90
+ const lines = buffer.split('\n');
91
+ // Keep the last partial line in the buffer
92
+ buffer = lines.pop() || '';
93
+ for (const line of lines) {
94
+ if (!line.trim())
95
+ continue;
96
+ try {
97
+ const obj = JSON.parse(line);
98
+ const pinoLevel = typeof obj.level === 'number' ? obj.level : 30;
99
+ const mappedLevel = mapPinoLevel(pinoLevel, levelMap);
100
+ const message = obj.msg || '';
101
+ // Extract attributes (everything except Pino internal fields)
102
+ const attributes = {};
103
+ for (const key of Object.keys(obj)) {
104
+ if (!PINO_INTERNAL_FIELDS.has(key)) {
105
+ attributes[key] = obj[key];
106
+ }
107
+ }
108
+ // Lazy import to avoid circular dependency
109
+ const JA = require('../index').default;
110
+ if (JA && JA.logger) {
111
+ JA.logger.log(mappedLevel, message, attributes);
112
+ }
113
+ }
114
+ catch {
115
+ // Skip malformed JSON lines
116
+ }
117
+ }
118
+ }
119
+ catch {
120
+ // Never throw from transport
121
+ }
122
+ callback();
123
+ },
124
+ final(callback) {
125
+ // Process any remaining data in the buffer
126
+ if (buffer.trim()) {
127
+ try {
128
+ const obj = JSON.parse(buffer);
129
+ const pinoLevel = typeof obj.level === 'number' ? obj.level : 30;
130
+ const mappedLevel = mapPinoLevel(pinoLevel, levelMap);
131
+ const message = obj.msg || '';
132
+ const attributes = {};
133
+ for (const key of Object.keys(obj)) {
134
+ if (!PINO_INTERNAL_FIELDS.has(key)) {
135
+ attributes[key] = obj[key];
136
+ }
137
+ }
138
+ const JA = require('../index').default;
139
+ if (JA && JA.logger) {
140
+ JA.logger.log(mappedLevel, message, attributes);
141
+ }
142
+ }
143
+ catch {
144
+ // Skip malformed data
145
+ }
146
+ }
147
+ callback();
148
+ },
149
+ });
150
+ }
151
+ // Default export for Pino transport API: pino({ transport: { target: '...' } })
152
+ exports.default = createJustAnalyticsPinoTransport;
153
+ //# sourceMappingURL=pino.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino.js","sourceRoot":"","sources":["../../src/integrations/pino.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @file packages/node-sdk/src/integrations/redis.ts
3
+ * @description Redis auto-instrumentation integration for the JustAnalytics Node.js SDK.
4
+ *
5
+ * Implements Story 040 - Redis Auto-Instrumentation
6
+ *
7
+ * Monkey-patches `ioredis` (Redis.prototype.sendCommand) and/or `@redis/client`
8
+ * (Commander.prototype.sendCommand) to automatically create `redis.command` spans
9
+ * for all Redis operations. This captures all Redis traffic regardless of which
10
+ * higher-level abstraction the developer uses.
11
+ *
12
+ * Follows the same monkey-patching pattern established in Story 036 (HTTP Auto-Instrumentation)
13
+ * and Story 039 (PostgreSQL Auto-Instrumentation):
14
+ * - Integration class with `enable()`/`disable()` lifecycle methods
15
+ * - Original function preservation for clean teardown
16
+ * - Integration with AsyncLocalStorage context for automatic parent-child span relationships
17
+ * - Fail-open design: if instrumentation code fails, the original command executes normally
18
+ *
19
+ * CRITICAL SECURITY: Redis values are NEVER captured in span attributes.
20
+ * Only command name + key name(s) are recorded in `db.statement`.
21
+ *
22
+ * References:
23
+ * - OpenTelemetry Database Semantic Conventions (db.system, db.statement, etc.)
24
+ * - Story 035 - Node.js SDK Core (Span, context, transport)
25
+ * - Story 036 - HTTP Auto-Instrumentation (integration pattern)
26
+ * - Story 039 - PostgreSQL Auto-Instrumentation (database integration pattern)
27
+ */
28
+ import { Span } from '../span';
29
+ /**
30
+ * Configuration for the Redis auto-instrumentation integration.
31
+ */
32
+ export interface RedisIntegrationOptions {
33
+ /** Enable/disable the integration (default: true) */
34
+ enabled?: boolean;
35
+ /**
36
+ * Maximum character length for the db.statement attribute.
37
+ * Statements longer than this are truncated with '...' suffix.
38
+ * (default: 512)
39
+ */
40
+ maxStatementLength?: number;
41
+ }
42
+ /**
43
+ * Format the db.statement attribute from a Redis command and its arguments.
44
+ *
45
+ * Rules:
46
+ * 1. Command name is always UPPERCASE
47
+ * 2. For NO_KEY_COMMANDS, statement is just the command name
48
+ * 3. For known commands, include only key name(s) per KEY_ONLY_COMMANDS mapping
49
+ * 4. For unknown commands, include only the first argument (assumed to be the key)
50
+ * 5. Values are NEVER included
51
+ * 6. Truncate to maxStatementLength
52
+ *
53
+ * @param command - Redis command name (e.g., "get", "SET", "hget")
54
+ * @param args - Command arguments array
55
+ * @param maxLength - Maximum statement length (default: 512)
56
+ * @returns Formatted statement (e.g., "GET user:123", "HGET cache:data field")
57
+ */
58
+ export declare function formatRedisStatement(command: string, args: unknown[], maxLength?: number): string;
59
+ /**
60
+ * Sanitize a Redis connection string by masking the password.
61
+ *
62
+ * Also handles raw redis:// URLs by replacing the password portion.
63
+ *
64
+ * @param connStr - Raw connection string potentially containing a password
65
+ * @returns Sanitized connection string with password masked
66
+ */
67
+ export declare function sanitizeRedisConnectionString(connStr: string): string;
68
+ /**
69
+ * Build a sanitized Redis connection string from individual components.
70
+ *
71
+ * @param host - Redis host
72
+ * @param port - Redis port
73
+ * @param password - Redis password (will be masked)
74
+ * @param db - Redis database index
75
+ * @param user - Redis user (for ACL auth)
76
+ * @returns Sanitized connection string (e.g., "redis://user:***@host:6379/0")
77
+ */
78
+ export declare function sanitizeRedisConnectionString(host: string, port: number, password?: string, db?: number, user?: string): string;
79
+ /**
80
+ * RedisIntegration monkey-patches ioredis and/or @redis/client
81
+ * to auto-create redis.command spans for all Redis operations.
82
+ *
83
+ * Follows the same pattern as HttpIntegration (Story 036) and
84
+ * PgIntegration (Story 039):
85
+ * - Constructor accepts serviceName, options, onSpanEnd callback
86
+ * - enable() patches, disable() restores
87
+ * - Original functions preserved for clean teardown
88
+ * - Fail-open design: instrumentation failures never crash the host process
89
+ *
90
+ * Security: NEVER captures Redis values in span attributes.
91
+ * Only command name + key name(s) are recorded.
92
+ */
93
+ export declare class RedisIntegration {
94
+ private _enabled;
95
+ private _options;
96
+ private _serviceName;
97
+ private _onSpanEnd;
98
+ private _originalIoRedisSendCommand;
99
+ private _ioRedisPrototype;
100
+ private _originalNodeRedisSendCommand;
101
+ private _nodeRedisPrototype;
102
+ /**
103
+ * Create a new RedisIntegration.
104
+ *
105
+ * @param serviceName - The service name for span attribution
106
+ * @param options - Integration configuration options
107
+ * @param onSpanEnd - Callback invoked when a span ends (enqueues to transport)
108
+ */
109
+ constructor(serviceName: string, options: RedisIntegrationOptions | undefined, onSpanEnd: (span: Span) => void);
110
+ /**
111
+ * Activate the integration: load Redis modules and patch prototypes.
112
+ *
113
+ * Attempts to load both ioredis and @redis/client independently.
114
+ * If neither is installed, silently skips. If only one is installed,
115
+ * only that library is patched.
116
+ *
117
+ * Calling enable() when already enabled is a no-op (idempotent).
118
+ */
119
+ enable(): void;
120
+ /**
121
+ * Deactivate: restore original Redis functions.
122
+ *
123
+ * Calling disable() when not enabled is a no-op (idempotent).
124
+ */
125
+ disable(): void;
126
+ /**
127
+ * Attempt to load and patch ioredis.
128
+ *
129
+ * ioredis routes ALL commands (including pipeline/cluster) through
130
+ * Redis.prototype.sendCommand. By patching this one method, we capture
131
+ * all commands regardless of which method the developer calls.
132
+ */
133
+ private _patchIoRedis;
134
+ /**
135
+ * Attempt to load and patch @redis/client.
136
+ *
137
+ * node-redis v4+ uses a Commander class. All commands go through
138
+ * sendCommand(args: string[]) where args[0] is the command name.
139
+ */
140
+ private _patchNodeRedis;
141
+ /**
142
+ * Restore all patched functions to their originals.
143
+ */
144
+ private _restoreOriginals;
145
+ /**
146
+ * Wrap ioredis Redis.prototype.sendCommand to create redis.command spans.
147
+ *
148
+ * ioredis routes ALL commands (including pipeline/cluster) through
149
+ * sendCommand(command: Command). The Command object has:
150
+ * - command.name: string (e.g., "get", "set", "hget")
151
+ * - command.args: unknown[] (command arguments)
152
+ * - command.promise: Promise (resolves/rejects when the command completes)
153
+ *
154
+ * @param original - The original sendCommand function
155
+ * @returns A wrapped version
156
+ */
157
+ private _wrapIoRedisSendCommand;
158
+ /**
159
+ * Wrap @redis/client's sendCommand to create redis.command spans.
160
+ *
161
+ * node-redis v4+ uses a Commander class that dispatches all commands
162
+ * through a sendCommand method. The method signature is:
163
+ * sendCommand(args: string[], options?: CommandOptions): Promise<unknown>
164
+ *
165
+ * Where args[0] is the command name and args[1..] are command arguments.
166
+ *
167
+ * @param original - The original sendCommand function
168
+ * @returns A wrapped version
169
+ */
170
+ private _wrapNodeRedisSendCommand;
171
+ /**
172
+ * Extract connection info from an ioredis client instance.
173
+ *
174
+ * ioredis stores connection options on the instance as `this.options`.
175
+ *
176
+ * @param client - The ioredis client instance (`this` in the patched method)
177
+ * @returns Attributes object with connection info
178
+ */
179
+ private _getIoRedisConnectionInfo;
180
+ /**
181
+ * Extract connection info from a @redis/client instance.
182
+ *
183
+ * node-redis v4+ stores connection options in various ways depending
184
+ * on the version. We try multiple paths defensively.
185
+ *
186
+ * @param client - The @redis/client instance (`this` in the patched method)
187
+ * @returns Attributes object with connection info
188
+ */
189
+ private _getNodeRedisConnectionInfo;
190
+ }