@foam-ai/node-cliengo 0.1.0-alpha.12 → 0.1.0-alpha.14

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.
@@ -13,7 +13,7 @@
13
13
  * a service needs to call e.g. injectJobData() from a file that doesn't have
14
14
  * access to the foam instance.
15
15
  */
16
- export { init } from './init';
16
+ export { init, getFoam } from './init';
17
17
  export { buildTraceparent, extractParentContext, getTraceContext } from './trace-bridge';
18
18
  export { injectSnsAttributes } from './sns';
19
19
  export { injectJobData, wrapJobConsumer } from './job';
@@ -15,9 +15,10 @@
15
15
  * access to the foam instance.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.FOAM_OTEL_ENDPOINT = exports.createPinoMixin = exports.createWinstonFormat = exports.getFastifyRequestTraceContext = exports.createFastifyPlugin = exports.createPinoHttpOptions = exports.getRequestTraceContext = exports.createExpressErrorHandler = exports.createExpressMiddleware = exports.wrapSqsConsumer = exports.wrapJobConsumer = exports.injectJobData = exports.injectSnsAttributes = exports.getTraceContext = exports.extractParentContext = exports.buildTraceparent = exports.init = void 0;
18
+ exports.FOAM_OTEL_ENDPOINT = exports.createPinoMixin = exports.createWinstonFormat = exports.getFastifyRequestTraceContext = exports.createFastifyPlugin = exports.createPinoHttpOptions = exports.getRequestTraceContext = exports.createExpressErrorHandler = exports.createExpressMiddleware = exports.wrapSqsConsumer = exports.wrapJobConsumer = exports.injectJobData = exports.injectSnsAttributes = exports.getTraceContext = exports.extractParentContext = exports.buildTraceparent = exports.getFoam = exports.init = void 0;
19
19
  var init_1 = require("./init");
20
20
  Object.defineProperty(exports, "init", { enumerable: true, get: function () { return init_1.init; } });
21
+ Object.defineProperty(exports, "getFoam", { enumerable: true, get: function () { return init_1.getFoam; } });
21
22
  var trace_bridge_1 = require("./trace-bridge");
22
23
  Object.defineProperty(exports, "buildTraceparent", { enumerable: true, get: function () { return trace_bridge_1.buildTraceparent; } });
23
24
  Object.defineProperty(exports, "extractParentContext", { enumerable: true, get: function () { return trace_bridge_1.extractParentContext; } });
@@ -24,8 +24,7 @@
24
24
  * features (trace propagation, log enrichment, NR bridging) still work.
25
25
  * - Token undefined + forceExport: throws (fail-fast — you asked to force
26
26
  * export but provided no credentials).
27
- * - Custom endpoint without forceExport: throws. Production always uses the
28
- * default Foam endpoint; custom endpoints are only for dev/staging.
27
+ * - Endpoint is always the production Foam endpoint not configurable.
29
28
  * - Auto-shutdown (SIGTERM/SIGINT): flushes all providers with 5s timeout,
30
29
  * then calls process.exit(0). Without the explicit exit, registering
31
30
  * process.on('SIGTERM') replaces Node's default terminate behavior — services
@@ -50,4 +49,10 @@
50
49
  * global registrations.
51
50
  */
52
51
  import type { InitOptions, FoamInstance } from './types';
53
- export declare function init(serviceName: string, token?: string, options?: InitOptions): FoamInstance;
52
+ export declare function init(serviceName: string, options?: InitOptions): FoamInstance;
53
+ /**
54
+ * Returns the Foam instance for the given service name (or the only instance
55
+ * if there's just one). Call this from any module after init() has run —
56
+ * no circular dependency, no holder pattern needed.
57
+ */
58
+ export declare function getFoam(serviceName?: string): FoamInstance | undefined;
@@ -25,8 +25,7 @@
25
25
  * features (trace propagation, log enrichment, NR bridging) still work.
26
26
  * - Token undefined + forceExport: throws (fail-fast — you asked to force
27
27
  * export but provided no credentials).
28
- * - Custom endpoint without forceExport: throws. Production always uses the
29
- * default Foam endpoint; custom endpoints are only for dev/staging.
28
+ * - Endpoint is always the production Foam endpoint not configurable.
30
29
  * - Auto-shutdown (SIGTERM/SIGINT): flushes all providers with 5s timeout,
31
30
  * then calls process.exit(0). Without the explicit exit, registering
32
31
  * process.on('SIGTERM') replaces Node's default terminate behavior — services
@@ -52,6 +51,7 @@
52
51
  */
53
52
  Object.defineProperty(exports, "__esModule", { value: true });
54
53
  exports.init = init;
54
+ exports.getFoam = getFoam;
55
55
  const api_1 = require("@opentelemetry/api");
56
56
  const exporter_logs_otlp_http_1 = require("@opentelemetry/exporter-logs-otlp-http");
57
57
  const exporter_metrics_otlp_http_1 = require("@opentelemetry/exporter-metrics-otlp-http");
@@ -104,6 +104,11 @@ function createInertInstance(serviceName) {
104
104
  createPinoDestination: () => new node_stream_1.Writable({
105
105
  write: (_c, _e, cb) => cb(),
106
106
  }),
107
+ createPinoLogger: (opts = {}) => {
108
+ const pino = require('pino');
109
+ return pino({ ...opts });
110
+ },
111
+ createPinoHttpConfig: () => ({}),
107
112
  buildTraceparent: trace_bridge_1.buildTraceparent,
108
113
  injectSnsAttributes: sns_1.injectSnsAttributes,
109
114
  injectJobData: job_1.injectJobData,
@@ -117,7 +122,7 @@ function createInertInstance(serviceName) {
117
122
  };
118
123
  }
119
124
  /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
120
- function init(serviceName, token, options = {}) {
125
+ function init(serviceName, options = {}) {
121
126
  const existing = instances.get(serviceName);
122
127
  if (existing) {
123
128
  // eslint-disable-next-line no-console
@@ -134,23 +139,21 @@ function init(serviceName, token, options = {}) {
134
139
  }
135
140
  // Resolve NR
136
141
  (0, nr_1.resolveNewRelic)(options.newrelic);
142
+ const token = options.token;
137
143
  // Production gate
138
144
  const isProduction = process.env.NODE_ENV === 'production';
139
145
  const shouldExport = isProduction || (options.forceExport === true);
140
146
  // Token validation
141
147
  if (shouldExport && !token) {
142
148
  if (options.forceExport) {
143
- throw new Error('[foam] forceExport is true but no FOAM_OTEL_TOKEN provided — cannot export telemetry');
149
+ throw new Error('[foam] forceExport is true but no token provided — cannot export telemetry');
144
150
  }
145
151
  // eslint-disable-next-line no-console
146
- console.warn('[foam] no FOAM_OTEL_TOKEN — OTLP export disabled');
152
+ console.warn('[foam] no token provided — OTLP export disabled');
147
153
  }
148
154
  const hasToken = Boolean(token);
149
155
  const canExport = shouldExport && hasToken;
150
- if (options.endpoint && !options.forceExport) {
151
- throw new Error('[foam] custom endpoint requires forceExport: true — production always uses the default Foam endpoint');
152
- }
153
- const endpoint = options.endpoint ?? constants_1.FOAM_OTEL_ENDPOINT;
156
+ const endpoint = constants_1.FOAM_OTEL_ENDPOINT;
154
157
  const resource = (0, resources_1.resourceFromAttributes)({ 'service.name': serviceName });
155
158
  const authHeaders = token
156
159
  ? { Authorization: `Bearer ${token}` }
@@ -342,6 +345,19 @@ function init(serviceName, token, options = {}) {
342
345
  createPinoMixin: () => (0, pino_mixin_1.createPinoMixin)(),
343
346
  createPinoHttpOptions: () => (0, express_1.createPinoHttpOptions)(),
344
347
  createPinoDestination: () => (0, pino_destination_1.createPinoDestination)(loggerProvider, serviceName),
348
+ createPinoLogger: (opts = {}) => {
349
+ const pino = require('pino');
350
+ const mixin = (0, pino_mixin_1.createPinoMixin)();
351
+ const dest = (0, pino_destination_1.createPinoDestination)(loggerProvider, serviceName);
352
+ return pino({ ...opts, mixin }, pino.multistream([
353
+ { stream: process.stdout },
354
+ { stream: dest },
355
+ ]));
356
+ },
357
+ createPinoHttpConfig: () => {
358
+ const pinoHttpOpts = (0, express_1.createPinoHttpOptions)();
359
+ return { ...pinoHttpOpts };
360
+ },
345
361
  buildTraceparent: trace_bridge_1.buildTraceparent,
346
362
  injectSnsAttributes: sns_1.injectSnsAttributes,
347
363
  injectJobData: job_1.injectJobData,
@@ -354,3 +370,17 @@ function init(serviceName, token, options = {}) {
354
370
  return foam;
355
371
  }
356
372
  /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
373
+ /**
374
+ * Returns the Foam instance for the given service name (or the only instance
375
+ * if there's just one). Call this from any module after init() has run —
376
+ * no circular dependency, no holder pattern needed.
377
+ */
378
+ function getFoam(serviceName) {
379
+ if (serviceName) {
380
+ return instances.get(serviceName);
381
+ }
382
+ if (instances.size === 1) {
383
+ return instances.values().next().value;
384
+ }
385
+ return undefined;
386
+ }
@@ -27,12 +27,12 @@ import type { MeterProvider } from '@opentelemetry/sdk-metrics';
27
27
  import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
28
28
  export interface InitOptions {
29
29
  enabled?: boolean;
30
+ token?: string;
30
31
  newrelic?: NewRelicAgent;
31
32
  winston?: WinstonLogger;
32
33
  enableTraces?: boolean;
33
34
  enableLogs?: boolean;
34
35
  enableMetrics?: boolean;
35
- endpoint?: string;
36
36
  forceExport?: boolean;
37
37
  autoShutdown?: boolean;
38
38
  }
@@ -65,6 +65,8 @@ export interface FoamInstance {
65
65
  customProps: (req: any) => Record<string, string>;
66
66
  };
67
67
  createPinoDestination(): NodeJS.WritableStream;
68
+ createPinoLogger(options?: Record<string, any>): any;
69
+ createPinoHttpConfig(): Record<string, any>;
68
70
  buildTraceparent(): string;
69
71
  injectSnsAttributes(attrs: Record<string, SnsMessageAttributeValue>): Record<string, SnsMessageAttributeValue>;
70
72
  injectJobData<T extends Record<string, unknown>>(data: T): T & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foam-ai/node-cliengo",
3
- "version": "0.1.0-alpha.12",
3
+ "version": "0.1.0-alpha.14",
4
4
  "description": "Unified observability (traces, logs, metrics) for Cliengo Node.js services, connecting New Relic APM with Foam's OTel collector.",
5
5
  "main": "dist/node-cliengo/src/index.js",
6
6
  "types": "dist/node-cliengo/src/index.d.ts",