@seeka-labs/sdk-apps-server-telemetry-logging 3.9.10 → 3.9.12

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.
@@ -1 +1 @@
1
- import{OTLPLogExporter as g}from"@opentelemetry/exporter-logs-otlp-proto";import{HttpInstrumentation as S}from"@opentelemetry/instrumentation-http";import{UndiciInstrumentation as L}from"@opentelemetry/instrumentation-undici";import{WinstonInstrumentation as P}from"@opentelemetry/instrumentation-winston";import{BatchLogRecordProcessor as I}from"@opentelemetry/sdk-logs";import{resourceFromAttributes as h}from"@opentelemetry/resources";import{NodeSDK as w}from"@opentelemetry/sdk-node";import{ATTR_SERVICE_NAME as N,ATTR_SERVICE_VERSION as A}from"@opentelemetry/semantic-conventions";var c=class{constructor(r){this.wrapped=r}onEmit(r,t){let n=r.attributes;if(n)for(let e of Object.keys(n)){let a=n[e];if(!this.isValidAttributeValue(a))try{n[e]=JSON.stringify(a)}catch{n[e]=String(a)}}this.wrapped.onEmit(r,t)}shutdown(){return this.wrapped.shutdown()}forceFlush(){return this.wrapped.forceFlush()}isValidAttributeValue(r){return r==null||typeof r=="string"||typeof r=="number"||typeof r=="boolean"?!0:Array.isArray(r)?r.every(t=>typeof t=="string"||typeof t=="number"||typeof t=="boolean"):!1}};var o=null,E=null,m="__SEEKA_OTEL_REGISTERED__",H=(i,r,t,n,e,a)=>{let l=h({[N]:i,[A]:r,"service.namespace":"devapp","service.instance.id":e.WEBSITE_ROLE_INSTANCE_ID,"faas.name":e.WEBSITE_SITE_NAME,"faas.instance":e.WEBSITE_ROLE_INSTANCE_ID,"faas.version":e.OTEL_SERVICE_VERSION,"deployment.environment":e.NODE_ENV,"cloud.region":e.REGION_NAME,"cloud.provider":t,"cloud.platform":n,"seeka.app.id":e.SEEKA_APP_ID?.replace(/-/g,""),"seeka.app.name":i,...a});if(e.OTEL_SDK_DISABLED==="true")return l;if(global[m]==!0||o)return console.warn("[otel] OpenTelemetry SDK already started"),l;global[m]=!0;let u=[],d=e.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT||e.OTEL_EXPORTER_OTLP_ENDPOINT;if(d){let s=e.OTEL_EXPORTER_OTLP_LOGS_HEADERS||e.OTEL_EXPORTER_OTLP_HEADERS,f={};s&&(f=s.split(",").reduce((y,T)=>{let[O,R]=T.split("=");return{...y,[O]:R}},{})),E=new g({url:d,headers:f});let _=new I(E);u.push(new c(_))}o=new w({resource:l,instrumentations:[new P({disableLogSending:!0}),new L,new S],logRecordProcessors:u});try{o.start(),e.NODE_ENV!=="production"&&console.log("[otel] OpenTelemetry SDK started")}catch(s){console.error("[otel] OpenTelemetry SDK failed to start",s)}let p=async()=>{try{if(!o)return;await o.shutdown(),console.log("[otel] OpenTelemetry SDK shut down")}catch(s){console.error("[otel] Error during OpenTelemetry shutdown",s)}};return process.on("SIGTERM",p),process.on("SIGINT",p),l},M=async()=>{try{o&&typeof o.forceFlush=="function"&&await o.forceFlush()}catch(i){console.error("[otel] forceFlush failed",i)}};export{M as forceFlushOpenTelemetry,H as registerSeekaAppOpenTelemetry};
1
+ import{OTLPLogExporter as H}from"@opentelemetry/exporter-logs-otlp-proto";import{HttpInstrumentation as D}from"@opentelemetry/instrumentation-http";import{UndiciInstrumentation as C}from"@opentelemetry/instrumentation-undici";import{WinstonInstrumentation as K}from"@opentelemetry/instrumentation-winston";import{envDetector as v,hostDetector as q}from"@opentelemetry/resources";import{BatchLogRecordProcessor as V}from"@opentelemetry/sdk-logs";import{resourceFromAttributes as j}from"@opentelemetry/resources";import{NodeSDK as F}from"@opentelemetry/sdk-node";import{ATTR_SERVICE_NAME as M,ATTR_SERVICE_VERSION as U}from"@opentelemetry/semantic-conventions";var S=class{constructor(n){this.wrapped=n}onEmit(n,p){let c=n.attributes;if(c){let e=Object.keys(c),s={},u=[];for(let a of e){let i=c[a];if(!this.isValidAttributeValue(i))if(i!==null&&typeof i=="object"&&!Array.isArray(i))this.flattenObject(i,a,s),u.push(a);else try{c[a]=JSON.stringify(i)}catch{c[a]=String(i)}}for(let a of u)delete c[a];for(let[a,i]of Object.entries(s))c[a]=i}this.wrapped.onEmit(n,p)}shutdown(){return this.wrapped.shutdown()}forceFlush(){return this.wrapped.forceFlush()}flattenObject(n,p,c){for(let[e,s]of Object.entries(n)){let u=`${p}.${e}`;if(s!==null&&typeof s=="object"&&!Array.isArray(s))this.flattenObject(s,u,c);else if(this.isValidAttributeValue(s))c[u]=s;else try{c[u]=JSON.stringify(s)}catch{c[u]=String(s)}}}isValidAttributeValue(n){return n==null||typeof n=="string"||typeof n=="number"||typeof n=="boolean"?!0:Array.isArray(n)?n.every(p=>typeof p=="string"||typeof p=="number"||typeof p=="boolean"):!1}};import{BatchSpanProcessor as G}from"@opentelemetry/sdk-trace-node";import{OTLPTraceExporter as X}from"@opentelemetry/exporter-trace-otlp-proto";import{SpanKind as B,trace as Q,context as $}from"@opentelemetry/api";var T=null,P=null,b=null,x=[],L=[],N="__SEEKA_OTEL_REGISTERED__",z=Q.getTracer("winston-profiles"),me=(f,n,p,c,e,s,u,a)=>{let i=j({[M]:f,[U]:n,"service.namespace":"devapp","service.instance.id":e.WEBSITE_ROLE_INSTANCE_ID,"faas.name":e.WEBSITE_SITE_NAME,"faas.instance":e.WEBSITE_ROLE_INSTANCE_ID,"faas.version":e.OTEL_SERVICE_VERSION,"deployment.environment":e.NODE_ENV,"cloud.region":e.REGION_NAME,"cloud.provider":p,"cloud.platform":c,"seeka.app.id":e.SEEKA_APP_ID?.replace(/-/g,""),"seeka.app.name":f,...s});if(e.OTEL_SDK_DISABLED==="true")return i;if(global[N]==!0||T)return console.warn("[otel] OpenTelemetry SDK already started"),i;global[N]=!0;let l=e.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT||e.OTEL_EXPORTER_OTLP_ENDPOINT;if(console.log("[otel] Logs exporter URL:",l),l){let r=e.OTEL_EXPORTER_OTLP_LOGS_HEADERS||e.OTEL_EXPORTER_OTLP_HEADERS,t={};r&&(t=r.split(",").reduce((o,g)=>{let[m,R]=g.split("=");return{...o,[m]:R}},{})),P=new H({url:l,headers:t});let d=new V(P);x.push(new S(d))}let E=e.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT||e.OTEL_EXPORTER_OTLP_ENDPOINT;if(console.log("[otel] Traces exporter URL:",E),E){let r=e.OTEL_EXPORTER_OTLP_TRACES_HEADERS||e.OTEL_EXPORTER_OTLP_HEADERS,t={};r&&(t=r.split(",").reduce((o,g)=>{let[m,R]=g.split("=");return{...o,[m]:R}},{})),b=new X({url:E,headers:t});let d=new G(b);L.push(d)}let y={resource:i,resourceDetectors:[v,q],instrumentations:[new K({logHook:(r,t)=>{if(t.durationMs&&t.message){let d=Date.now(),o=d-t.durationMs;z.startSpan(t.message,{kind:B.INTERNAL,startTime:o},$.active()).end(d)}}}),new C,new D],logRecordProcessors:x,spanProcessors:L};T=new F(a?a(y):y);try{T.start(),e.NODE_ENV!=="production"&&console.log("[otel] OpenTelemetry SDK started"),u&&u(i)}catch(r){console.error("[otel] OpenTelemetry SDK failed to start",r)}let O=async()=>{try{if(!T)return;await T.shutdown(),console.log("[otel] OpenTelemetry SDK shut down")}catch(r){console.error("[otel] Error during OpenTelemetry shutdown",r)}};return process.on("SIGTERM",O),process.on("SIGINT",O),i},fe=async()=>{try{T&&typeof T.forceFlush=="function"&&await T.forceFlush()}catch(f){console.error("[otel] forceFlush failed",f)}};import{trace as w,SpanKind as W,SpanStatusCode as _,context as h,propagation as J}from"@opentelemetry/api";async function Ee(f,n,p,c={}){let{url:e,method:s,headers:u}=f,{invocationId:a}=n,{spanName:i,route:l,attributes:E={},tracerName:y="http-middleware"}=c,O=w.getTracer(y),r=J.extract(h.active(),u,{get(o,g){return o.get(g)??void 0},keys(o){return Array.from(o.keys())}}),t=null;try{t=new URL(e)}catch{}let d=i||`${s} ${l||t?.pathname||e}`;return h.with(r,async()=>O.startActiveSpan(d,{kind:W.SERVER,attributes:{"http.method":s,"http.url":e,...l&&{"http.route":l},...t&&{"http.scheme":t.protocol.replace(":",""),"http.host":t.host,"http.target":t.pathname+t.search,"net.host.name":t.hostname,...t.port&&{"net.host.port":parseInt(t.port,10)}},...a&&{"faas.invocation_id":a},...Object.fromEntries(Object.entries(E).filter(([,o])=>o!==void 0))}},async o=>{let g=w.setSpan(h.active(),o);return h.with(g,async()=>{try{let m=await p(),R=m.status??200;return o.setAttribute("http.status_code",R),R>=400?o.setStatus({code:_.ERROR,message:`HTTP ${R}`}):o.setStatus({code:_.OK}),m}catch(m){throw o.recordException(m),o.setStatus({code:_.ERROR,message:m.message}),o.setAttribute("http.status_code",500),m}finally{o.end()}})}))}import{trace as A,SpanKind as Y,SpanStatusCode as k,context as I}from"@opentelemetry/api";async function Oe(f,n,p,c={}){let{queueName:e,messageId:s,dequeueCount:u}=f,{invocationId:a}=n,{spanName:i,attributes:l={},tracerName:E="queue-middleware"}=c,y=A.getTracer(E),O=i||`queue ${e}`;return y.startActiveSpan(O,{kind:Y.CONSUMER,attributes:{"messaging.system":"azure_storage_queue","messaging.destination":e,"messaging.destination_kind":"queue","messaging.operation":"process",...s&&{"messaging.message_id":s},...u!==void 0&&{"messaging.azure.dequeue_count":u},...a&&{"faas.invocation_id":a},...Object.fromEntries(Object.entries(l).filter(([,r])=>r!==void 0))}},async r=>{let t=A.setSpan(I.active(),r);return I.with(t,async()=>{try{let d=await p();return r.setStatus({code:k.OK}),d}catch(d){throw r.recordException(d),r.setStatus({code:k.ERROR,message:d.message}),d}finally{r.end()}})})}export{fe as forceFlushOpenTelemetry,me as registerSeekaAppOpenTelemetry,Ee as withOtelHttpTracing,Oe as withOtelQueueTracing};
@@ -1 +1,3 @@
1
1
  export * from './telemetry/register';
2
+ export * from './telemetry/middleware/http';
3
+ export * from './telemetry/middleware/queue';
@@ -0,0 +1,20 @@
1
+ import type { HeadersInit } from 'undici';
2
+ import type { ServerlessFunctionExecutionContext } from '@seeka-labs/sdk-apps-core';
3
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
4
+ export interface TracedHttpRequest {
5
+ url: string;
6
+ method: string;
7
+ headers: Headers;
8
+ }
9
+ export interface TracedHttpResponse {
10
+ status?: number;
11
+ headers?: HeadersInit;
12
+ }
13
+ export interface HttpTracingOptions {
14
+ spanName?: string;
15
+ route?: string;
16
+ attributes?: Record<string, string | number | boolean | undefined>;
17
+ tracerName?: string;
18
+ }
19
+ export type HttpHandler<TResponse extends TracedHttpResponse = TracedHttpResponse> = () => Promise<TResponse>;
20
+ export declare function withOtelHttpTracing<TResponse extends TracedHttpResponse>(request: TracedHttpRequest, context: ServerlessFunctionExecutionContext, handler: HttpHandler<TResponse>, options?: HttpTracingOptions): Promise<TResponse>;
@@ -0,0 +1,14 @@
1
+ import type { ServerlessFunctionExecutionContext } from '@seeka-labs/sdk-apps-core';
2
+ export interface TracedQueueMessage {
3
+ queueName: string;
4
+ message: unknown;
5
+ messageId?: string;
6
+ dequeueCount?: number;
7
+ }
8
+ export interface QueueTracingOptions {
9
+ spanName?: string;
10
+ attributes?: Record<string, string | number | boolean | undefined>;
11
+ tracerName?: string;
12
+ }
13
+ export type QueueHandler<TResult = void> = () => Promise<TResult>;
14
+ export declare function withOtelQueueTracing<TResult = void>(queueMessage: TracedQueueMessage, context: ServerlessFunctionExecutionContext, handler: QueueHandler<TResult>, options?: QueueTracingOptions): Promise<TResult>;
@@ -1,3 +1,4 @@
1
1
  import { type Resource } from '@opentelemetry/resources';
2
- export declare const registerSeekaAppOpenTelemetry: (appName: string, appVersion: string, cloudProvider: "azure" | "netlify" | "aws" | string, cloudPlatform: "azure_function" | "netlify_function" | "aws_lambda" | string, processEnv: NodeJS.ProcessEnv, resourceAttributes?: Record<string, any>) => Resource;
2
+ import type { NodeSDKConfiguration } from "@opentelemetry/sdk-node/build/src/types";
3
+ export declare const registerSeekaAppOpenTelemetry: (appName: string, appVersion: string, cloudProvider: "azure" | "netlify" | "aws" | string, cloudPlatform: "azure_function" | "netlify_function" | "aws_lambda" | string, processEnv: NodeJS.ProcessEnv, resourceAttributes?: Record<string, any>, afterStart?: (r: Resource) => void, configureOtel?: (config: Partial<NodeSDKConfiguration>) => Partial<NodeSDKConfiguration>) => Resource;
3
4
  export declare const forceFlushOpenTelemetry: () => Promise<void>;
@@ -6,5 +6,6 @@ export declare class SanitizingLogRecordProcessor implements LogRecordProcessor
6
6
  onEmit(logRecord: ReadableLogRecord, context?: Context): void;
7
7
  shutdown(): Promise<void>;
8
8
  forceFlush(): Promise<void>;
9
+ private flattenObject;
9
10
  private isValidAttributeValue;
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seeka-labs/sdk-apps-server-telemetry-logging",
3
- "version": "3.9.10",
3
+ "version": "3.9.12",
4
4
  "description": "Seeka - Apps SDK - Server Telemetry Logging (App health and logging)",
5
5
  "author": "SEEKA <platform@seeka.co>",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "@opentelemetry/instrumentation-winston": "*",
44
44
  "@opentelemetry/sdk-node": "*",
45
45
  "@opentelemetry/sdk-trace-node": "*",
46
- "@opentelemetry/winston-transport": "*",
46
+ "@seeka-labs/sdk-apps-core": "*",
47
47
  "undici": "^7",
48
48
  "winston": "^3"
49
49
  },
@@ -62,7 +62,6 @@
62
62
  "@opentelemetry/instrumentation-winston": "^0.53.0",
63
63
  "@opentelemetry/sdk-node": "^0.208.0",
64
64
  "@opentelemetry/sdk-trace-node": "^2.2.0",
65
- "@opentelemetry/winston-transport": "^0.19.0",
66
65
  "@types/node": "^22",
67
66
  "ava": "^6",
68
67
  "cross-env": "^10",
@@ -74,5 +73,5 @@
74
73
  "undici": "^7",
75
74
  "winston": "^3"
76
75
  },
77
- "gitHead": "71ffbf517682c7878af5604dcbf30e87a16124a1"
76
+ "gitHead": "97482e0073b38db42f1ce49682cc837ed29c12b9"
78
77
  }