@hemia/trace-manager 0.0.4 → 0.0.6
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{asyncContext as t}from"@hemia/app-context";var e;!function(t){t.TRACE="x-trace-id",t.CORRELATION="x-correlation-id"}(e||(e={}));const r={DEBUG:5,INFO:9,WARN:13,ERROR:17,FATAL:21};const n=new class{constructor(t){this.defaultServiceName=t}log(e,n,o){const s=t.getStore();if(!s)return console.warn("[Logger] No active context. Log not traced."),void console.log(`[${e}] ${n}`,o);const i={Timestamp:(new Date).toISOString(),TraceId:s.traceId,SpanId:s.spanId,TraceFlags:1,SeverityText:e,SeverityNumber:r[e],ServiceName:s.serviceName,Body:n,LogAttributes:this.stringifyAttributes(o||{}),ResourceAttributes:s.traceContext.resourceAttributes};s.traceContext.logs.push(i),"production"!==process.env.NODE_ENV&&console.log(`[${e}] [TraceId:${s.traceId.substring(0,8)}...] ${n}`,o||"")}stringifyAttributes(t){const e={};for(const[r,n]of Object.entries(t))if(null==n)e[r]="";else if("string"==typeof n)e[r]=n;else try{e[r]=JSON.stringify(n)}catch{e[r]=String(n)}return e}debug(t,e){this.log("DEBUG",t,e)}info(t,e){this.log("INFO",t,e)}warn(t,e){this.log("WARN",t,e)}error(t,e){this.log("ERROR",t,e)}fatal(t,e){this.log("FATAL",t,e)}};for(var o,s=[],i=0;i<256;++i)s.push((i+256).toString(16).slice(1));var a=new Uint8Array(16);function c(){if(!o&&!(o="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return o(a)}var p={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function u(t,e,r){if(p.randomUUID&&!t)return p.randomUUID();var n=(t=t||{}).random||(t.rng||c)();return n[6]=15&n[6]|64,n[8]=63&n[8]|128,function(t,e=0){return(s[t[e+0]]+s[t[e+1]]+s[t[e+2]]+s[t[e+3]]+"-"+s[t[e+4]]+s[t[e+5]]+"-"+s[t[e+6]]+s[t[e+7]]+"-"+s[t[e+8]]+s[t[e+9]]+"-"+s[t[e+10]]+s[t[e+11]]+s[t[e+12]]+s[t[e+13]]+s[t[e+14]]+s[t[e+15]]).toLowerCase()}(n)}function g(t,e){t["app.method.args.count"]=e.length.toString(),t["app.method.args.types"]=e.map(t=>typeof t).join(",")}function y(t,e){t["app.method.result.type"]=typeof e,t["app.method.result.isArray"]=Array.isArray(e).toString(),t["app.method.result.length"]=Array.isArray(e)?e.length.toString():"1"}function d(t,e,r="http.request.body"){if(t[`${r}.exists`]=(!!e).toString(),t[`${r}.type`]=typeof e,e&&"object"==typeof e){const n=Object.keys(e);t[`${r}.keys`]=n.join(","),t[`${r}.keyCount`]=n.length.toString()}Array.isArray(e)&&(t[`${r}.isArray`]="true",t[`${r}.length`]=e.length.toString())}function
|
|
1
|
+
import{asyncContext as t}from"@hemia/app-context";var e;!function(t){t.TRACE="x-trace-id",t.CORRELATION="x-correlation-id"}(e||(e={}));const r={DEBUG:5,INFO:9,WARN:13,ERROR:17,FATAL:21};const n=new class{constructor(t){this.defaultServiceName=t}log(e,n,o){const s=t.getStore();if(!s)return console.warn("[Logger] No active context. Log not traced."),void console.log(`[${e}] ${n}`,o);const i={Timestamp:(new Date).toISOString(),TraceId:s.traceId,SpanId:s.spanId,TraceFlags:1,SeverityText:e,SeverityNumber:r[e],ServiceName:s.serviceName,Body:n,LogAttributes:this.stringifyAttributes(o||{}),ResourceAttributes:s.traceContext.resourceAttributes};s.traceContext.logs.push(i),"production"!==process.env.NODE_ENV&&console.log(`[${e}] [TraceId:${s.traceId.substring(0,8)}...] ${n}`,o||"")}stringifyAttributes(t){const e={};for(const[r,n]of Object.entries(t))if(null==n)e[r]="";else if("string"==typeof n)e[r]=n;else try{e[r]=JSON.stringify(n)}catch{e[r]=String(n)}return e}debug(t,e){this.log("DEBUG",t,e)}info(t,e){this.log("INFO",t,e)}warn(t,e){this.log("WARN",t,e)}error(t,e){this.log("ERROR",t,e)}fatal(t,e){this.log("FATAL",t,e)}};for(var o,s=[],i=0;i<256;++i)s.push((i+256).toString(16).slice(1));var a=new Uint8Array(16);function c(){if(!o&&!(o="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return o(a)}var p={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function u(t,e,r){if(p.randomUUID&&!t)return p.randomUUID();var n=(t=t||{}).random||(t.rng||c)();return n[6]=15&n[6]|64,n[8]=63&n[8]|128,function(t,e=0){return(s[t[e+0]]+s[t[e+1]]+s[t[e+2]]+s[t[e+3]]+"-"+s[t[e+4]]+s[t[e+5]]+"-"+s[t[e+6]]+s[t[e+7]]+"-"+s[t[e+8]]+s[t[e+9]]+"-"+s[t[e+10]]+s[t[e+11]]+s[t[e+12]]+s[t[e+13]]+s[t[e+14]]+s[t[e+15]]).toLowerCase()}(n)}function g(t,e){t["app.method.args.count"]=e.length.toString(),t["app.method.args.types"]=e.map(t=>typeof t).join(",")}function y(t,e){t["app.method.result.type"]=typeof e,t["app.method.result.isArray"]=Array.isArray(e).toString(),t["app.method.result.length"]=Array.isArray(e)?e.length.toString():"1"}function d(t,e,r="http.request.body"){if(t[`${r}.exists`]=(!!e).toString(),t[`${r}.type`]=typeof e,e&&"object"==typeof e){const n=Object.keys(e);t[`${r}.keys`]=n.join(","),t[`${r}.keyCount`]=n.length.toString()}Array.isArray(e)&&(t[`${r}.isArray`]="true",t[`${r}.length`]=e.length.toString())}function f(t,e,r=!1,n="http.response.body"){if(t[`${n}.exists`]=(!!e).toString(),t[`${n}.type`]=typeof e,e&&"object"==typeof e){const r=Object.keys(e);t[`${n}.keys`]=r.join(","),t[`${n}.keyCount`]=r.length.toString()}Array.isArray(e)&&(t[`${n}.isArray`]="true",t[`${n}.length`]=e.length.toString()),r&&e&&(e.message&&(t["http.response.error.message"]=String(e.message).substring(0,500)),e.code&&(t["http.response.error.code"]=String(e.code)),e.error&&(t["http.response.error.type"]=String(e.error).substring(0,200)))}function l(t,e,r){if(e){if(t[`${r}.exists`]="true",t[`${r}.type`]=typeof e,"object"==typeof e&&!Array.isArray(e)){const n=Object.keys(e);t[`${r}.keys`]=n.join(","),t[`${r}.keyCount`]=n.length.toString()}Array.isArray(e)&&(t[`${r}.isArray`]="true",t[`${r}.length`]=e.length.toString(),e.length>0&&(t[`${r}.firstItemType`]=typeof e[0])),"string"==typeof e?t[`${r}.value`]=e.substring(0,200):"number"!=typeof e&&"boolean"!=typeof e||(t[`${r}.value`]=String(e))}else t[`${r}.exists`]="false"}function S(e){return function(r,n,o){const s=o?.value;if("function"!=typeof s)throw new Error("@Trace can only be applied to methods");o.value=async function(...o){const i=t.getStore();if(!i)return console.warn("[Trace] No active context. Skipping trace."),await s.apply(this,o);const a=u(),c=i.spanId,p=this?.constructor?.name||r.name||"UnknownClass",d=e?.name||`${p}.${n}`,f=process.hrtime.bigint(),l={Timestamp:(new Date).toISOString(),TraceId:i.traceId,SpanId:a,ParentSpanId:c,TraceState:"",ServiceName:i.serviceName,SpanName:d,SpanKind:e?.kind||"SPAN_KIND_INTERNAL",DurationUInt64:BigInt(0),StatusCode:"STATUS_CODE_UNSET",StatusMessage:"",SpanAttributes:{"code.function":n,"code.namespace":p,...e?.attributes},ResourceAttributes:i.traceContext.resourceAttributes,EventsNested:[],LinksNested:[]},S={...i,spanId:a};return t.run(S,async()=>{try{g(l.SpanAttributes,o);const t=await s.apply(this,o);return y(l.SpanAttributes,t),l.StatusCode="STATUS_CODE_OK",t}catch(t){const e={Timestamp:(new Date).toISOString(),Name:"exception",Attributes:{"exception.type":t.constructor?.name||"Error","exception.message":t.message,"exception.stacktrace":String(t.stack||"").substring(0,1e3)}};throw l.EventsNested.push(e),l.StatusCode="STATUS_CODE_ERROR",l.StatusMessage=t.message,t}finally{const t=process.hrtime.bigint();l.DurationUInt64=t-f,i.traceContext.spans.push(l)}})}}}function m(t){return function(e){for(const r of Object.getOwnPropertyNames(e.prototype)){const n=Object.getOwnPropertyDescriptor(e.prototype,r);if(!(n?.value instanceof Function)||"constructor"===r||t?.exclude?.includes(r))continue;S({name:`${e.name}.${r}`,kind:"SPAN_KIND_INTERNAL"})(e.prototype,r,n),Object.defineProperty(e.prototype,r,n)}}}export{S as Trace,e as TraceHeader,m as Traceable,g as addArgsMetadata,l as addObjectMetadata,d as addRequestBodyMetadata,f as addResponseBodyMetadata,y as addResultMetadata,n as logger};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t,e=require("@hemia/app-context");exports.TraceHeader=void 0,(t=exports.TraceHeader||(exports.TraceHeader={})).TRACE="x-trace-id",t.CORRELATION="x-correlation-id";const r={DEBUG:5,INFO:9,WARN:13,ERROR:17,FATAL:21};const
|
|
1
|
+
"use strict";var t,e=require("@hemia/app-context");exports.TraceHeader=void 0,(t=exports.TraceHeader||(exports.TraceHeader={})).TRACE="x-trace-id",t.CORRELATION="x-correlation-id";const r={DEBUG:5,INFO:9,WARN:13,ERROR:17,FATAL:21};const o=new class{constructor(t){this.defaultServiceName=t}log(t,o,n){const s=e.asyncContext.getStore();if(!s)return console.warn("[Logger] No active context. Log not traced."),void console.log(`[${t}] ${o}`,n);const a={Timestamp:(new Date).toISOString(),TraceId:s.traceId,SpanId:s.spanId,TraceFlags:1,SeverityText:t,SeverityNumber:r[t],ServiceName:s.serviceName,Body:o,LogAttributes:this.stringifyAttributes(n||{}),ResourceAttributes:s.traceContext.resourceAttributes};s.traceContext.logs.push(a),"production"!==process.env.NODE_ENV&&console.log(`[${t}] [TraceId:${s.traceId.substring(0,8)}...] ${o}`,n||"")}stringifyAttributes(t){const e={};for(const[r,o]of Object.entries(t))if(null==o)e[r]="";else if("string"==typeof o)e[r]=o;else try{e[r]=JSON.stringify(o)}catch{e[r]=String(o)}return e}debug(t,e){this.log("DEBUG",t,e)}info(t,e){this.log("INFO",t,e)}warn(t,e){this.log("WARN",t,e)}error(t,e){this.log("ERROR",t,e)}fatal(t,e){this.log("FATAL",t,e)}};for(var n,s=[],a=0;a<256;++a)s.push((a+256).toString(16).slice(1));var i=new Uint8Array(16);function c(){if(!n&&!(n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return n(i)}var p={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function u(t,e,r){if(p.randomUUID&&!t)return p.randomUUID();var o=(t=t||{}).random||(t.rng||c)();return o[6]=15&o[6]|64,o[8]=63&o[8]|128,function(t,e=0){return(s[t[e+0]]+s[t[e+1]]+s[t[e+2]]+s[t[e+3]]+"-"+s[t[e+4]]+s[t[e+5]]+"-"+s[t[e+6]]+s[t[e+7]]+"-"+s[t[e+8]]+s[t[e+9]]+"-"+s[t[e+10]]+s[t[e+11]]+s[t[e+12]]+s[t[e+13]]+s[t[e+14]]+s[t[e+15]]).toLowerCase()}(o)}function d(t,e){t["app.method.args.count"]=e.length.toString(),t["app.method.args.types"]=e.map(t=>typeof t).join(",")}function y(t,e){t["app.method.result.type"]=typeof e,t["app.method.result.isArray"]=Array.isArray(e).toString(),t["app.method.result.length"]=Array.isArray(e)?e.length.toString():"1"}function g(t){return function(r,o,n){const s=n?.value;if("function"!=typeof s)throw new Error("@Trace can only be applied to methods");n.value=async function(...n){const a=e.asyncContext.getStore();if(!a)return console.warn("[Trace] No active context. Skipping trace."),await s.apply(this,n);const i=u(),c=a.spanId,p=this?.constructor?.name||r.name||"UnknownClass",g=t?.name||`${p}.${o}`,l=process.hrtime.bigint(),f={Timestamp:(new Date).toISOString(),TraceId:a.traceId,SpanId:i,ParentSpanId:c,TraceState:"",ServiceName:a.serviceName,SpanName:g,SpanKind:t?.kind||"SPAN_KIND_INTERNAL",DurationUInt64:BigInt(0),StatusCode:"STATUS_CODE_UNSET",StatusMessage:"",SpanAttributes:{"code.function":o,"code.namespace":p,...t?.attributes},ResourceAttributes:a.traceContext.resourceAttributes,EventsNested:[],LinksNested:[]},S={...a,spanId:i};return e.asyncContext.run(S,async()=>{try{d(f.SpanAttributes,n);const t=await s.apply(this,n);return y(f.SpanAttributes,t),f.StatusCode="STATUS_CODE_OK",t}catch(t){const e={Timestamp:(new Date).toISOString(),Name:"exception",Attributes:{"exception.type":t.constructor?.name||"Error","exception.message":t.message,"exception.stacktrace":String(t.stack||"").substring(0,1e3)}};throw f.EventsNested.push(e),f.StatusCode="STATUS_CODE_ERROR",f.StatusMessage=t.message,t}finally{const t=process.hrtime.bigint();f.DurationUInt64=t-l,a.traceContext.spans.push(f)}})}}}exports.Trace=g,exports.Traceable=function(t){return function(e){for(const r of Object.getOwnPropertyNames(e.prototype)){const o=Object.getOwnPropertyDescriptor(e.prototype,r);if(!(o?.value instanceof Function)||"constructor"===r||t?.exclude?.includes(r))continue;g({name:`${e.name}.${r}`,kind:"SPAN_KIND_INTERNAL"})(e.prototype,r,o),Object.defineProperty(e.prototype,r,o)}}},exports.addArgsMetadata=d,exports.addObjectMetadata=function(t,e,r){if(e){if(t[`${r}.exists`]="true",t[`${r}.type`]=typeof e,"object"==typeof e&&!Array.isArray(e)){const o=Object.keys(e);t[`${r}.keys`]=o.join(","),t[`${r}.keyCount`]=o.length.toString()}Array.isArray(e)&&(t[`${r}.isArray`]="true",t[`${r}.length`]=e.length.toString(),e.length>0&&(t[`${r}.firstItemType`]=typeof e[0])),"string"==typeof e?t[`${r}.value`]=e.substring(0,200):"number"!=typeof e&&"boolean"!=typeof e||(t[`${r}.value`]=String(e))}else t[`${r}.exists`]="false"},exports.addRequestBodyMetadata=function(t,e,r="http.request.body"){if(t[`${r}.exists`]=(!!e).toString(),t[`${r}.type`]=typeof e,e&&"object"==typeof e){const o=Object.keys(e);t[`${r}.keys`]=o.join(","),t[`${r}.keyCount`]=o.length.toString()}Array.isArray(e)&&(t[`${r}.isArray`]="true",t[`${r}.length`]=e.length.toString())},exports.addResponseBodyMetadata=function(t,e,r=!1,o="http.response.body"){if(t[`${o}.exists`]=(!!e).toString(),t[`${o}.type`]=typeof e,e&&"object"==typeof e){const r=Object.keys(e);t[`${o}.keys`]=r.join(","),t[`${o}.keyCount`]=r.length.toString()}Array.isArray(e)&&(t[`${o}.isArray`]="true",t[`${o}.length`]=e.length.toString()),r&&e&&(e.message&&(t["http.response.error.message"]=String(e.message).substring(0,500)),e.code&&(t["http.response.error.code"]=String(e.code)),e.error&&(t["http.response.error.type"]=String(e.error).substring(0,200)))},exports.addResultMetadata=y,exports.logger=o;
|
|
@@ -4,3 +4,9 @@ import { TraceOptions } from "../types/traceOptions";
|
|
|
4
4
|
* Usa AsyncLocalStorage para propagar contexto automáticamente
|
|
5
5
|
*/
|
|
6
6
|
export declare function Trace(options?: TraceOptions): <T extends (...args: any[]) => any>(target: any, key: string, descriptor: PropertyDescriptor) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Aplica @Trace automáticamente a todos los métodos de la clase
|
|
9
|
+
*/
|
|
10
|
+
export declare function Traceable(options?: {
|
|
11
|
+
exclude?: string[];
|
|
12
|
+
}): (constructor: Function) => void;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { TraceHeader } from "./types/traceHeadersNames";
|
|
|
2
2
|
export { TraceContext } from "./types/traceContext";
|
|
3
3
|
export { TraceOptions } from "./types/traceOptions";
|
|
4
4
|
export { logger } from "./log/Logger";
|
|
5
|
-
export { Trace } from "./decorator/Traceable";
|
|
5
|
+
export { Trace, Traceable } from "./decorator/Traceable";
|
|
6
6
|
export { addArgsMetadata, addResultMetadata, addRequestBodyMetadata, addResponseBodyMetadata, addObjectMetadata } from "./utils/SpanAttributesHelper";
|
package/package.json
CHANGED