@hemia/trace-manager 0.0.1 → 0.0.2

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.
package/README.md CHANGED
@@ -101,8 +101,7 @@ interface TraceNode {
101
101
 
102
102
  ## Requisitos
103
103
 
104
- * `@hemia/db-manager` y `@hemia/app-context` para contexto y persistencia
105
- * MongoDB como backend de traza
104
+ * `@hemia/app-context` para contexto y persistencia
106
105
 
107
106
  ---
108
107
 
@@ -1 +1 @@
1
- import{asyncContext as t}from"@hemia/app-context";import{Schema as e}from"@hemia/db-manager";var r;function n(t){try{const e=JSON.stringify(t,function(){const t=new WeakSet;return(e,r)=>{if(null===r)return null;if("object"==typeof r){if(t.has(r))return"[Circular]";t.add(r)}return"function"==typeof r?r.toString():r}}());return JSON.parse(e)}catch(e){return String(t)}}!function(t){t.TRACE="x-trace-id",t.CORRELATION="x-correlation-id"}(r||(r={}));const o=["content-type","host","x-no-cookies","x-api-key","Authorization","origin"];function i(t){return t.map(t=>{if(function(t){return null!=t&&"object"==typeof t&&"string"==typeof t.method&&"string"==typeof t.url&&"object"==typeof t.headers}(t)){const e=o.reduce((e,r)=>{const n=r.toLowerCase();return t.headers[n]&&(e[n]=t.headers[n]),e},{});return{method:t.method,url:t.url,params:t.params,query:t.query,body:t.body,headers:e}}return function(t){return null!=t&&"object"==typeof t&&"number"==typeof t.statusCode&&"function"==typeof t.setHeader&&"function"==typeof t.end}(t)?"[ExpressResponseObject]":"function"==typeof t?"[Function next]":t})}for(var a,p=[],c=0;c<256;++c)p.push((c+256).toString(16).slice(1));var s=new Uint8Array(16);function u(){if(!a&&!(a="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 a(s)}var y={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function d(t,e,r){if(y.randomUUID&&!t)return y.randomUUID();var n=(t=t||{}).random||(t.rng||u)();return n[6]=15&n[6]|64,n[8]=63&n[8]|128,function(t,e=0){return(p[t[e+0]]+p[t[e+1]]+p[t[e+2]]+p[t[e+3]]+"-"+p[t[e+4]]+p[t[e+5]]+"-"+p[t[e+6]]+p[t[e+7]]+"-"+p[t[e+8]]+p[t[e+9]]+"-"+p[t[e+10]]+p[t[e+11]]+p[t[e+12]]+p[t[e+13]]+p[t[e+14]]+p[t[e+15]]).toLowerCase()}(n)}function f(t){return function(e,r,o){const a="function"==typeof e;if(o){const p=o.value;if("function"!=typeof p)throw new Error("@Traceable can only be applied to methods, but was applied to "+typeof p);o.value=async function(...o){const c=a?e.name:this?.constructor?.name||e.constructor.name||"DEFAULT_CHECKPOINT",s=r;let u="";try{const e=n(i(o));u=g(t?.ck||c,t?.fn||s,"input",e,t?.description,t?.tags,t?.source)}catch(t){console.error("Error in Traceable decorator (addTrace):",t)}try{const t=await p.apply(this,o),e=Array.isArray(t)?t:[t],r=n(i(e));return m(u,!0,n(r)),t}catch(t){throw m(u,!1,n({error:t}),!0),t}}}else{const o=e[r];if("function"!=typeof o)throw new Error(`@Traceable can only be applied to methods, but was applied to ${typeof o}, without descriptor`);e[r]=async function(...p){const c=a?e.name:this?.constructor?.name||e.constructor.name||"DEFAULT_CHECKPOINT",s=r;let u="";try{const e=n(i(p));u=g(t?.ck||c,t?.fn||s,"input",e,t?.description,t?.tags,t?.source)}catch(t){console.error("Error in Traceable decorator (addTrace):",t)}try{const t=await o.apply(this,p),e=Array.isArray(t)?t:[t],r=n(i(e));return m(u,!0,n(r)),t}catch(t){throw m(u,!1,n({error:t}),!0),t}}}}}function g(e,r,n,o,i,a,p){const c=t.getStore();if(!c)return"";const s=c.projectId||"unknown",u=c.traceId,y=d(),f={description:i||"new trace input",tags:a,endTime:0,traceId:u,projectId:s,spanId:y,parentSpanId:c.parentSpanId,checkpoint:e,function:r,status:!0,type:n,startTime:Date.now(),inputData:o,source:p||"api"};return c.parentSpanId=y,c.trace.trace.push(f),y}function m(e,r,n,o){const i=t.getStore();if(!i)return;const a=i.trace.trace.find(t=>t.spanId===e);a&&(a.status=r,a.type="output",a.duration=Date.now()-a.startTime,a.endTime=Date.now(),a.outputData=n,o&&(a.error=n))}class l{constructor(t){this.repository=t}async save(t,e={}){if(!this.repository)throw new Error("Manager no inicializado. Llama a TraceManager primero.");const r={timestamp:(new Date).toISOString(),traceId:t,...e};return await this.repository.create(r)}async find(t,e){return await this.repository.find(t,e)}async findOne(t){return await this.repository.findOne(t)}async getById(t){return await this.repository.findById(t)}async update(t,e,r){return await this.repository.update(t,e,r)}async delete(t,e){await this.repository.delete(t,e)}async aggregate(t,e){return await this.repository.aggregate(t,e)}}const S=new e({traceId:{type:String,required:!0},projectId:{type:String,required:!0},meta:{userAgent:{type:String},environment:{type:String},platform:{type:String},ip:{type:String},event:{type:String},url:{type:String},path:{type:String},route:{type:String},tags:[{type:String}],user:{id:{type:String},email:{type:String}},browser:{name:{type:String},version:{type:String}},os:{name:{type:String},version:{type:String}},device:{model:{type:String},type:{type:String},vendor:{type:String}}},trace:{type:[new e({description:{type:String},traceId:{type:String,required:!0},spanId:{type:String,required:!0},parentSpanId:{type:String},projectId:{type:String,required:!0},parentId:{type:Number},checkpoint:{type:String,required:!0},function:{type:String,required:!0},status:{type:Boolean,required:!0},type:{type:String,enum:["input","output"],required:!0},startTime:{type:Number,default:()=>Date.now()},endTime:{type:Number,default:()=>Date.now()},duration:{type:Number},inputData:{type:e.Types.Mixed},outputData:{type:e.Types.Mixed},additionalData:{type:e.Types.Mixed},tags:[{type:String}],source:{type:String},error:{message:{type:String},code:{type:String},stack:{type:String}}},{_id:!1})],required:!0}});export{r as TraceHeader,l as TraceManager,S as TraceSchema,f as Traceable};
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 n={DEBUG:5,INFO:9,WARN:13,ERROR:17,FATAL:21};const r=new class{constructor(t){this.defaultServiceName=t}log(e,r,o){const s=t.getStore();if(!s)return console.warn("[Logger] No active context. Log not traced."),void console.log(`[${e}] ${r}`,o);const a={Timestamp:(new Date).toISOString(),TraceId:s.traceId,SpanId:s.spanId,TraceFlags:1,SeverityText:e,SeverityNumber:n[e],ServiceName:s.serviceName,Body:r,LogAttributes:this.stringifyAttributes(o||{}),ResourceAttributes:s.traceContext.resourceAttributes};s.traceContext.logs.push(a),"production"!==process.env.NODE_ENV&&console.log(`[${e}] [TraceId:${s.traceId.substring(0,8)}...] ${r}`,o||"")}stringifyAttributes(t){const e={};for(const[n,r]of Object.entries(t))if(null==r)e[n]="";else if("string"==typeof r)e[n]=r;else try{e[n]=JSON.stringify(r)}catch{e[n]=String(r)}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)}};function o(t){try{const e=JSON.stringify(t,function(){const t=new WeakSet;return(e,n)=>{if(null===n)return null;if("object"==typeof n){if(t.has(n))return"[Circular]";t.add(n)}return"function"==typeof n?n.toString():n}}());return JSON.parse(e)}catch(e){return String(t)}}const s=["content-type","host","x-no-cookies","x-api-key","Authorization","origin"];function a(t){return t.map(t=>{if(function(t){return null!=t&&"object"==typeof t&&"string"==typeof t.method&&"string"==typeof t.url&&"object"==typeof t.headers}(t)){const e=s.reduce((e,n)=>{const r=n.toLowerCase();return t.headers[r]&&(e[r]=t.headers[r]),e},{});return{method:t.method,url:t.url,params:t.params,query:t.query,body:t.body,headers:e}}return function(t){return null!=t&&"object"==typeof t&&"number"==typeof t.statusCode&&"function"==typeof t.setHeader&&"function"==typeof t.end}(t)?"[ExpressResponseObject]":"function"==typeof t?"[Function next]":t})}for(var i,c=[],u=0;u<256;++u)c.push((u+256).toString(16).slice(1));var p=new Uint8Array(16);function d(){if(!i&&!(i="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 i(p)}var f={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function g(t,e,n){if(f.randomUUID&&!t)return f.randomUUID();var r=(t=t||{}).random||(t.rng||d)();return r[6]=15&r[6]|64,r[8]=63&r[8]|128,function(t,e=0){return(c[t[e+0]]+c[t[e+1]]+c[t[e+2]]+c[t[e+3]]+"-"+c[t[e+4]]+c[t[e+5]]+"-"+c[t[e+6]]+c[t[e+7]]+"-"+c[t[e+8]]+c[t[e+9]]+"-"+c[t[e+10]]+c[t[e+11]]+c[t[e+12]]+c[t[e+13]]+c[t[e+14]]+c[t[e+15]]).toLowerCase()}(r)}function l(e){return function(n,r,s){const i=s?.value;if("function"!=typeof i)throw new Error("@Trace can only be applied to methods");s.value=async function(...s){const c=t.getStore();if(!c)return console.warn("[Trace] No active context. Skipping trace."),await i.apply(this,s);const u=g(),p=this?.constructor?.name||n.name||"UnknownClass",d=e?.name||`${p}.${r}`,f=process.hrtime.bigint(),l=(new Date).toISOString(),m=c.spanId,y={Timestamp:l,TraceId:c.traceId,SpanId:u,ParentSpanId:m,TraceState:"",ServiceName:c.serviceName,SpanName:d,SpanKind:e?.kind||"SPAN_KIND_INTERNAL",DurationUInt64:BigInt(0),StatusCode:"STATUS_CODE_UNSET",StatusMessage:"",SpanAttributes:{"code.function":r,"code.namespace":p,...e?.attributes},ResourceAttributes:c.traceContext.resourceAttributes,EventsNested:[],LinksNested:[]},S=c.spanId;c.spanId=u;try{const t=a(s);y.SpanAttributes["app.method.args"]=o(t),y.SpanAttributes["app.method.args.count"]=s.length.toString();const e=await i.apply(this,s),n=o(a(Array.isArray(e)?e:[e]));return y.SpanAttributes["app.method.result"]=n.substring(0,2e3),y.StatusCode="STATUS_CODE_OK",e}catch(t){const e={Timestamp:(new Date).toISOString(),Name:"exception",Attributes:{"exception.type":t.constructor?.name||"Error","exception.message":t.message||"Unknown error","exception.stacktrace":(t.stack||"").substring(0,5e3)}};throw y.EventsNested.push(e),y.StatusCode="STATUS_CODE_ERROR",y.StatusMessage=t.message||"Unhandled exception",t}finally{const t=process.hrtime.bigint();y.DurationUInt64=t-f,c.traceContext.spans.push(y),c.spanId=S}}}}export{l as Trace,e as TraceHeader,r as logger};
@@ -1 +1 @@
1
- "use strict";var t,e=require("@hemia/app-context"),r=require("@hemia/db-manager");function n(t){try{const e=JSON.stringify(t,function(){const t=new WeakSet;return(e,r)=>{if(null===r)return null;if("object"==typeof r){if(t.has(r))return"[Circular]";t.add(r)}return"function"==typeof r?r.toString():r}}());return JSON.parse(e)}catch(e){return String(t)}}exports.TraceHeader=void 0,(t=exports.TraceHeader||(exports.TraceHeader={})).TRACE="x-trace-id",t.CORRELATION="x-correlation-id";const o=["content-type","host","x-no-cookies","x-api-key","Authorization","origin"];function a(t){return t.map(t=>{if(function(t){return null!=t&&"object"==typeof t&&"string"==typeof t.method&&"string"==typeof t.url&&"object"==typeof t.headers}(t)){const e=o.reduce((e,r)=>{const n=r.toLowerCase();return t.headers[n]&&(e[n]=t.headers[n]),e},{});return{method:t.method,url:t.url,params:t.params,query:t.query,body:t.body,headers:e}}return function(t){return null!=t&&"object"==typeof t&&"number"==typeof t.statusCode&&"function"==typeof t.setHeader&&"function"==typeof t.end}(t)?"[ExpressResponseObject]":"function"==typeof t?"[Function next]":t})}for(var i,p=[],c=0;c<256;++c)p.push((c+256).toString(16).slice(1));var s=new Uint8Array(16);function u(){if(!i&&!(i="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 i(s)}var y={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function d(t,e,r){if(y.randomUUID&&!t)return y.randomUUID();var n=(t=t||{}).random||(t.rng||u)();return n[6]=15&n[6]|64,n[8]=63&n[8]|128,function(t,e=0){return(p[t[e+0]]+p[t[e+1]]+p[t[e+2]]+p[t[e+3]]+"-"+p[t[e+4]]+p[t[e+5]]+"-"+p[t[e+6]]+p[t[e+7]]+"-"+p[t[e+8]]+p[t[e+9]]+"-"+p[t[e+10]]+p[t[e+11]]+p[t[e+12]]+p[t[e+13]]+p[t[e+14]]+p[t[e+15]]).toLowerCase()}(n)}function f(t,r,n,o,a,i,p){const c=e.asyncContext.getStore();if(!c)return"";const s=c.projectId||"unknown",u=c.traceId,y=d(),f={description:a||"new trace input",tags:i,endTime:0,traceId:u,projectId:s,spanId:y,parentSpanId:c.parentSpanId,checkpoint:t,function:r,status:!0,type:n,startTime:Date.now(),inputData:o,source:p||"api"};return c.parentSpanId=y,c.trace.trace.push(f),y}function g(t,r,n,o){const a=e.asyncContext.getStore();if(!a)return;const i=a.trace.trace.find(e=>e.spanId===t);i&&(i.status=r,i.type="output",i.duration=Date.now()-i.startTime,i.endTime=Date.now(),i.outputData=n,o&&(i.error=n))}const m=new r.Schema({traceId:{type:String,required:!0},projectId:{type:String,required:!0},meta:{userAgent:{type:String},environment:{type:String},platform:{type:String},ip:{type:String},event:{type:String},url:{type:String},path:{type:String},route:{type:String},tags:[{type:String}],user:{id:{type:String},email:{type:String}},browser:{name:{type:String},version:{type:String}},os:{name:{type:String},version:{type:String}},device:{model:{type:String},type:{type:String},vendor:{type:String}}},trace:{type:[new r.Schema({description:{type:String},traceId:{type:String,required:!0},spanId:{type:String,required:!0},parentSpanId:{type:String},projectId:{type:String,required:!0},parentId:{type:Number},checkpoint:{type:String,required:!0},function:{type:String,required:!0},status:{type:Boolean,required:!0},type:{type:String,enum:["input","output"],required:!0},startTime:{type:Number,default:()=>Date.now()},endTime:{type:Number,default:()=>Date.now()},duration:{type:Number},inputData:{type:r.Schema.Types.Mixed},outputData:{type:r.Schema.Types.Mixed},additionalData:{type:r.Schema.Types.Mixed},tags:[{type:String}],source:{type:String},error:{message:{type:String},code:{type:String},stack:{type:String}}},{_id:!1})],required:!0}});exports.TraceManager=class{constructor(t){this.repository=t}async save(t,e={}){if(!this.repository)throw new Error("Manager no inicializado. Llama a TraceManager primero.");const r={timestamp:(new Date).toISOString(),traceId:t,...e};return await this.repository.create(r)}async find(t,e){return await this.repository.find(t,e)}async findOne(t){return await this.repository.findOne(t)}async getById(t){return await this.repository.findById(t)}async update(t,e,r){return await this.repository.update(t,e,r)}async delete(t,e){await this.repository.delete(t,e)}async aggregate(t,e){return await this.repository.aggregate(t,e)}},exports.TraceSchema=m,exports.Traceable=function(t){return function(e,r,o){const i="function"==typeof e;if(o){const p=o.value;if("function"!=typeof p)throw new Error("@Traceable can only be applied to methods, but was applied to "+typeof p);o.value=async function(...o){const c=i?e.name:this?.constructor?.name||e.constructor.name||"DEFAULT_CHECKPOINT",s=r;let u="";try{const e=n(a(o));u=f(t?.ck||c,t?.fn||s,"input",e,t?.description,t?.tags,t?.source)}catch(t){console.error("Error in Traceable decorator (addTrace):",t)}try{const t=await p.apply(this,o),e=Array.isArray(t)?t:[t],r=n(a(e));return g(u,!0,n(r)),t}catch(t){throw g(u,!1,n({error:t}),!0),t}}}else{const o=e[r];if("function"!=typeof o)throw new Error(`@Traceable can only be applied to methods, but was applied to ${typeof o}, without descriptor`);e[r]=async function(...p){const c=i?e.name:this?.constructor?.name||e.constructor.name||"DEFAULT_CHECKPOINT",s=r;let u="";try{const e=n(a(p));u=f(t?.ck||c,t?.fn||s,"input",e,t?.description,t?.tags,t?.source)}catch(t){console.error("Error in Traceable decorator (addTrace):",t)}try{const t=await o.apply(this,p),e=Array.isArray(t)?t:[t],r=n(a(e));return g(u,!0,n(r)),t}catch(t){throw g(u,!1,n({error:t}),!0),t}}}}};
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 n=new class{constructor(t){this.defaultServiceName=t}log(t,n,o){const s=e.asyncContext.getStore();if(!s)return console.warn("[Logger] No active context. Log not traced."),void console.log(`[${t}] ${n}`,o);const a={Timestamp:(new Date).toISOString(),TraceId:s.traceId,SpanId:s.spanId,TraceFlags:1,SeverityText:t,SeverityNumber:r[t],ServiceName:s.serviceName,Body:n,LogAttributes:this.stringifyAttributes(o||{}),ResourceAttributes:s.traceContext.resourceAttributes};s.traceContext.logs.push(a),"production"!==process.env.NODE_ENV&&console.log(`[${t}] [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)}};function o(t){try{const e=JSON.stringify(t,function(){const t=new WeakSet;return(e,r)=>{if(null===r)return null;if("object"==typeof r){if(t.has(r))return"[Circular]";t.add(r)}return"function"==typeof r?r.toString():r}}());return JSON.parse(e)}catch(e){return String(t)}}const s=["content-type","host","x-no-cookies","x-api-key","Authorization","origin"];function a(t){return t.map(t=>{if(function(t){return null!=t&&"object"==typeof t&&"string"==typeof t.method&&"string"==typeof t.url&&"object"==typeof t.headers}(t)){const e=s.reduce((e,r)=>{const n=r.toLowerCase();return t.headers[n]&&(e[n]=t.headers[n]),e},{});return{method:t.method,url:t.url,params:t.params,query:t.query,body:t.body,headers:e}}return function(t){return null!=t&&"object"==typeof t&&"number"==typeof t.statusCode&&"function"==typeof t.setHeader&&"function"==typeof t.end}(t)?"[ExpressResponseObject]":"function"==typeof t?"[Function next]":t})}for(var i,c=[],u=0;u<256;++u)c.push((u+256).toString(16).slice(1));var p=new Uint8Array(16);function d(){if(!i&&!(i="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 i(p)}var f={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function g(t,e,r){if(f.randomUUID&&!t)return f.randomUUID();var n=(t=t||{}).random||(t.rng||d)();return n[6]=15&n[6]|64,n[8]=63&n[8]|128,function(t,e=0){return(c[t[e+0]]+c[t[e+1]]+c[t[e+2]]+c[t[e+3]]+"-"+c[t[e+4]]+c[t[e+5]]+"-"+c[t[e+6]]+c[t[e+7]]+"-"+c[t[e+8]]+c[t[e+9]]+"-"+c[t[e+10]]+c[t[e+11]]+c[t[e+12]]+c[t[e+13]]+c[t[e+14]]+c[t[e+15]]).toLowerCase()}(n)}exports.Trace=function(t){return function(r,n,s){const i=s?.value;if("function"!=typeof i)throw new Error("@Trace can only be applied to methods");s.value=async function(...s){const c=e.asyncContext.getStore();if(!c)return console.warn("[Trace] No active context. Skipping trace."),await i.apply(this,s);const u=g(),p=this?.constructor?.name||r.name||"UnknownClass",d=t?.name||`${p}.${n}`,f=process.hrtime.bigint(),l=(new Date).toISOString(),y=c.spanId,m={Timestamp:l,TraceId:c.traceId,SpanId:u,ParentSpanId:y,TraceState:"",ServiceName:c.serviceName,SpanName:d,SpanKind:t?.kind||"SPAN_KIND_INTERNAL",DurationUInt64:BigInt(0),StatusCode:"STATUS_CODE_UNSET",StatusMessage:"",SpanAttributes:{"code.function":n,"code.namespace":p,...t?.attributes},ResourceAttributes:c.traceContext.resourceAttributes,EventsNested:[],LinksNested:[]},S=c.spanId;c.spanId=u;try{const t=a(s);m.SpanAttributes["app.method.args"]=o(t),m.SpanAttributes["app.method.args.count"]=s.length.toString();const e=await i.apply(this,s),r=o(a(Array.isArray(e)?e:[e]));return m.SpanAttributes["app.method.result"]=r.substring(0,2e3),m.StatusCode="STATUS_CODE_OK",e}catch(t){const e={Timestamp:(new Date).toISOString(),Name:"exception",Attributes:{"exception.type":t.constructor?.name||"Error","exception.message":t.message||"Unknown error","exception.stacktrace":(t.stack||"").substring(0,5e3)}};throw m.EventsNested.push(e),m.StatusCode="STATUS_CODE_ERROR",m.StatusMessage=t.message||"Unhandled exception",t}finally{const t=process.hrtime.bigint();m.DurationUInt64=t-f,c.traceContext.spans.push(m),c.spanId=S}}}},exports.logger=n;
@@ -1,4 +1,6 @@
1
- import { ITraceOptions } from "../types/traceOptions";
2
- export declare function Traceable(options?: ITraceOptions): <T extends (...args: any[]) => any>(target: any, key: string, descriptor?: PropertyDescriptor) => void;
3
- export declare function addTrace(checkPoint: string, functionCode: string, type: "input" | "output", data?: any, description?: string, tags?: string[], source?: string): string;
4
- export declare function endTrace(spanId: string, status: boolean, data?: any, isError?: boolean): void;
1
+ import { TraceOptions } from "../types/traceOptions";
2
+ /**
3
+ * Decorador que captura método como Span en formato OpenTelemetry/ClickHouse
4
+ * Usa AsyncLocalStorage para propagar contexto automáticamente
5
+ */
6
+ export declare function Trace(options?: TraceOptions): <T extends (...args: any[]) => any>(target: any, key: string, descriptor: PropertyDescriptor) => void;
@@ -1,7 +1,5 @@
1
1
  export { TraceHeader } from "./types/traceHeadersNames";
2
2
  export { TraceContext } from "./types/traceContext";
3
- export { ITraceOptions } from "./types/traceOptions";
4
- export { Traceable } from "./decorator/Traceable";
5
- export { TraceManager } from "./TraceManager";
6
- export { Trace, ITrace } from "./types/traceModel";
7
- export { TraceSchema } from "./types/traceSchema";
3
+ export { TraceOptions } from "./types/traceOptions";
4
+ export { logger } from "./log/Logger";
5
+ export { Trace } from "./decorator/Traceable";
@@ -0,0 +1,15 @@
1
+ export declare class Logger {
2
+ private defaultServiceName?;
3
+ constructor(defaultServiceName?: string | undefined);
4
+ /**
5
+ * Logs que se correlacionan automáticamente con el TraceId activo
6
+ */
7
+ private log;
8
+ private stringifyAttributes;
9
+ debug(message: string, attributes?: Record<string, any>): void;
10
+ info(message: string, attributes?: Record<string, any>): void;
11
+ warn(message: string, attributes?: Record<string, any>): void;
12
+ error(message: string, attributes?: Record<string, any>): void;
13
+ fatal(message: string, attributes?: Record<string, any>): void;
14
+ }
15
+ export declare const logger: Logger;
@@ -1,19 +1,6 @@
1
- /**
2
- * Opciones para el trazado de la ejecución de una función o proceso.
3
- *
4
- * @property {string} ck - Clave o identificador único para el trazo.
5
- * @property {string} fn - Nombre de la función o proceso que se está trazando.
6
- * @property {string} st - Estado inicial o mensaje que indica el inicio del trazo.
7
- * @property {string} [errSt] - Estado o mensaje que describe el error (opcional).
8
- * @property {string} [errCode] - Código que identifica el tipo de error (opcional).
9
- */
10
- export interface ITraceOptions {
11
- ck?: string;
12
- fn?: string;
13
- st?: string;
14
- errSt?: string;
15
- errCode?: string;
16
- description?: string;
17
- tags?: string[];
18
- source?: 'api' | 'web' | 'mobile' | 'cron' | 'system' | string;
1
+ import { TraceSpan } from "@hemia/app-context";
2
+ export interface TraceOptions {
3
+ name?: string;
4
+ kind?: TraceSpan['SpanKind'];
5
+ attributes?: Record<string, string>;
19
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hemia/trace-manager",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Gestor de trazas para registrar logs, errores y evento",
5
5
  "main": "dist/hemia-trace-manager.js",
6
6
  "module": "dist/hemia-trace-manager.esm.js",
@@ -13,8 +13,8 @@
13
13
  "test": "jest --passWithNoTests --detectOpenHandles"
14
14
  },
15
15
  "devDependencies": {
16
- "@hemia/app-context": "^0.0.1",
17
- "@hemia/db-manager": "^0.0.1",
16
+ "@hemia/app-context": "^0.0.3",
17
+ "@hemia/db-manager": "^0.0.6",
18
18
  "@rollup/plugin-commonjs": "^26.0.1",
19
19
  "@rollup/plugin-json": "^6.1.0",
20
20
  "@rollup/plugin-node-resolve": "^15.2.3",
@@ -1,50 +0,0 @@
1
- import { AggregateOptions, ClientSession, NoSQLOptions, NoSQLRepository, PipelineStage, FilterQuery, Document } from "@hemia/db-manager";
2
- export declare class TraceManager<T extends Document> {
3
- private repository;
4
- constructor(service: NoSQLRepository<T>);
5
- /**
6
- * Servicio que permite guardar LOGS
7
- * @param level - Nivel del Log
8
- * @param message - Mensaje
9
- * @param traceId - Trace ID
10
- * @param trace - Traza
11
- * @param additionalData - Datos adicionales
12
- * @returns Documento guardado
13
- */
14
- save(traceId: string, additionalData?: Partial<T>): Promise<T | null>;
15
- /**
16
- * Servicio que permite buscar documentos en la colección
17
- * @param filter Filtros que se aplican en la colección
18
- * @returns Lista de documentos de la colección
19
- */
20
- find(filter: FilterQuery<T>, options?: NoSQLOptions): Promise<T[]>;
21
- /**
22
- * Servicio que permite buscar un documento en la colleción
23
- * @param filter - Filtros de la colección
24
- * @returns Documentos de la colección
25
- */
26
- findOne(filter: FilterQuery<T>): Promise<T | null>;
27
- /**
28
- * Servicio que permite obtener un documento por ID
29
- * @param id - Identificador del documento
30
- * @returns Documento
31
- */
32
- getById(id: string): Promise<T | null>;
33
- /**
34
- * Serivicio para actualizar documentos en la base de datos
35
- * @param filter - criterio de actualización
36
- * @param updateData - Datos del documento a actualizar
37
- * @returns Documento actualizado
38
- */
39
- update(filter: FilterQuery<T>, updateData: Partial<T>, session?: ClientSession): Promise<T | null>;
40
- /**
41
- * Servicio para eliminar un documento de la base de datos
42
- * @param id - Identificador del documento
43
- * @returns Documento Eliminado
44
- */
45
- delete(filter: FilterQuery<T>, session?: ClientSession): Promise<void>;
46
- /**
47
- * Ejecuta una consulta de agregación con un pipeline personalizado.
48
- */
49
- aggregate(pipeline: PipelineStage[], options?: AggregateOptions): Promise<any[]>;
50
- }
@@ -1,63 +0,0 @@
1
- import { Document } from "mongoose";
2
- export interface ITrace extends Document {
3
- traceId: string;
4
- projectId: string;
5
- meta?: TraceMetadata;
6
- trace: Trace[];
7
- }
8
- /**
9
- * Node de las trazas
10
- */
11
- export interface Trace {
12
- description: string;
13
- traceId: string;
14
- spanId: string;
15
- parentSpanId: string;
16
- projectId: string;
17
- parentId?: number;
18
- checkpoint: string;
19
- function: string;
20
- status: boolean;
21
- type: "input" | "output";
22
- startTime: number;
23
- endTime?: number;
24
- duration?: number;
25
- inputData?: any;
26
- outputData?: any;
27
- additionalData?: any;
28
- tags?: string[];
29
- error?: {
30
- message: string;
31
- code?: string;
32
- stack?: string;
33
- };
34
- source?: 'api' | 'web' | 'mobile' | 'cron' | 'system' | string;
35
- }
36
- export interface TraceMetadata {
37
- userAgent: string | null;
38
- environment: string | null;
39
- platform: string | null;
40
- ip: string | null;
41
- user: {
42
- id: string;
43
- email: string;
44
- } | null;
45
- event: string;
46
- url: string;
47
- path: string;
48
- route: string | null;
49
- tags: string[];
50
- browser: {
51
- name: string | null;
52
- version: string | null;
53
- };
54
- os: {
55
- name: string | null;
56
- version: string | null;
57
- };
58
- device: {
59
- model: string | null;
60
- type: string | null;
61
- vendor: string | null;
62
- };
63
- }
@@ -1,11 +0,0 @@
1
- import { Schema } from "@hemia/db-manager";
2
- import { ITrace } from "./traceModel";
3
- export declare const TraceSchema: Schema<ITrace, import("mongoose").Model<ITrace, any, any, any, import("mongoose").Document<unknown, any, ITrace, any, {}> & ITrace & Required<{
4
- _id: unknown;
5
- }> & {
6
- __v: number;
7
- }, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, ITrace, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<ITrace>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<ITrace> & Required<{
8
- _id: unknown;
9
- }> & {
10
- __v: number;
11
- }>;