koatty_trace
Advanced tools
Comparing version 1.12.0 to 1.12.1
@@ -0,0 +0,0 @@ /* |
@@ -5,2 +5,14 @@ # Changelog | ||
### [1.12.1](https://github.com/koatty/koatty_trace/compare/v1.12.0...v1.12.1) (2024-01-24) | ||
### Bug Fixes | ||
* setTag ([e8ce324](https://github.com/koatty/koatty_trace/commit/e8ce3247a3b1ff1ecd55fa26c4541c05a0867d0b)) | ||
### Refactor | ||
* exception ([57b7f51](https://github.com/koatty/koatty_trace/commit/57b7f511dcbd891e2b15f2e3cf8885cf4b1d87f4)) | ||
## [1.12.0](https://github.com/koatty/koatty_trace/compare/v1.11.2...v1.12.0) (2024-01-21) | ||
@@ -7,0 +19,0 @@ |
/*! | ||
* @Author: richen | ||
* @Date: 2024-01-21 13:45:15 | ||
* @Date: 2024-01-24 11:10:28 | ||
* @License: BSD (3-Clause) | ||
@@ -8,9 +8,5 @@ * @Copyright (c) - <richenlin(at)gmail.com> | ||
*/ | ||
/// <reference types="node" /> | ||
import { IncomingMessage } from 'http'; | ||
import { Koatty } from 'koatty_core'; | ||
import { KoattyContext } from 'koatty_core'; | ||
import { KoattyNext } from 'koatty_core'; | ||
import { ServerResponse } from 'http'; | ||
@@ -24,3 +20,3 @@ /** | ||
*/ | ||
export declare function Trace(options: TraceOptions, app: Koatty): (ctx: KoattyContext, next: KoattyNext) => Promise<ServerResponse<IncomingMessage>>; | ||
export declare function Trace(options: TraceOptions, app: Koatty): (ctx: KoattyContext, next: KoattyNext) => Promise<any>; | ||
@@ -27,0 +23,0 @@ /** |
/*! | ||
* @Author: richen | ||
* @Date: 2024-01-21 13:45:05 | ||
* @Date: 2024-01-24 11:10:14 | ||
* @License: BSD (3-Clause) | ||
@@ -11,30 +11,11 @@ * @Copyright (c) - <richenlin(at)gmail.com> | ||
var uuid = require('uuid'); | ||
var Helper = require('koatty_lib'); | ||
var koatty_lib = require('koatty_lib'); | ||
var koatty_container = require('koatty_container'); | ||
var opentracing = require('opentracing'); | ||
var async_hooks = require('async_hooks'); | ||
var stream = require('stream'); | ||
var koatty_exception = require('koatty_exception'); | ||
var koatty_logger = require('koatty_logger'); | ||
var util = require('util'); | ||
var stream = require('stream'); | ||
function _interopNamespaceDefault(e) { | ||
var n = Object.create(null); | ||
if (e) { | ||
Object.keys(e).forEach(function (k) { | ||
if (k !== 'default') { | ||
var d = Object.getOwnPropertyDescriptor(e, k); | ||
Object.defineProperty(n, k, d.get ? d : { | ||
enumerable: true, | ||
get: function () { return e[k]; } | ||
}); | ||
} | ||
}); | ||
} | ||
n.default = e; | ||
return Object.freeze(n); | ||
} | ||
var Helper__namespace = /*#__PURE__*/_interopNamespaceDefault(Helper); | ||
/* | ||
@@ -115,20 +96,21 @@ * @Description: | ||
* @Date: 2022-02-21 11:32:03 | ||
* @LastEditTime: 2024-01-21 12:56:26 | ||
* @LastEditTime: 2024-01-24 10:45:24 | ||
*/ | ||
/** | ||
* Global Error handler | ||
* | ||
* @template T | ||
* @param {KoattyContext} ctx | ||
* @param {(Exception | T)} err | ||
*/ | ||
function catcher(ctx, span, err, globalErrorHandler) { | ||
// 如果是异常对象,直接返回 | ||
if (koatty_exception.isException(err)) { | ||
return err.setSpan(span).handler(ctx); | ||
* Global Error handler | ||
* @param ctx | ||
* @param err | ||
* @param span | ||
* @param globalErrorHandler | ||
* @param ext | ||
* @returns | ||
*/ | ||
function catcher(ctx, err, span, globalErrorHandler, ext) { | ||
err.message = err.message || ctx.message || ""; | ||
if (err.message.includes('"')) { | ||
err.message = err.message.replaceAll('"', '\\"'); | ||
} | ||
// 执行自定义全局异常处理 | ||
const message = (err.message).includes('"') ? (err.message).replaceAll('"', '\\"') : err.message; | ||
if (globalErrorHandler) { | ||
const ins = new globalErrorHandler(message, err.code ?? 1, err.status || 500, err.stack, span); | ||
const ins = new globalErrorHandler(err.message, err.code ?? 1, err.status || 500, err.stack, span); | ||
if (ins.handler) { | ||
@@ -138,13 +120,12 @@ return ins.handler(ctx); | ||
} | ||
// 如果是异常对象,直接返回 | ||
if (koatty_exception.isException(err)) { | ||
return err.setSpan(span).handler(ctx); | ||
} | ||
// 使用默认异常处理 | ||
return new koatty_exception.Exception(message, err.code ?? 1, err.status || 500, err.stack, span).handler(ctx); | ||
return new koatty_exception.Exception(err.message, 1, 500, err.stack, span).handler(ctx); | ||
} | ||
/* | ||
* @Description: | ||
* @Usage: | ||
* @Author: richen | ||
* @Date: 2021-11-19 00:14:59 | ||
* @LastEditTime: 2024-01-14 11:53:13 | ||
*/ | ||
// StatusEmpty | ||
const StatusEmpty = [204, 205, 304]; | ||
/** | ||
@@ -158,8 +139,2 @@ * httpHandler | ||
const timeout = ext.timeout || 10000; | ||
// set ctx start time | ||
Helper.Helper.define(ctx, 'startTime', Date.now()); | ||
// http version | ||
Helper.Helper.define(ctx, 'version', ctx.req.httpVersion); | ||
// originalPath | ||
Helper.Helper.define(ctx, 'originalPath', ctx.path); | ||
// Encoding | ||
@@ -179,5 +154,8 @@ ctx.encoding = ext.encoding; | ||
const now = Date.now(); | ||
const msg = `{"action":"${ctx.method}","code":"${ctx.status}","startTime":"${ctx.startTime}","duration":"${(now - ctx.startTime) || 0}","requestId":"${ext.requestId}","endTime":"${now}","path":"${ctx.originalPath || '/'}"}`; | ||
const msg = `{"action":"${ctx.method}","code":"${ctx.status}","startTime":"${ctx.startTime}","duration":"${(now - ctx.startTime) || 0}","requestId":"${ctx.requestId}","endTime":"${now}","path":"${ctx.originalPath || '/'}"}`; | ||
koatty_logger.DefaultLogger[(ctx.status >= 400 ? 'Error' : 'Info')](msg); | ||
if (span) { | ||
span.setTag(opentracing.Tags.HTTP_STATUS_CODE, ctx.status); | ||
span.setTag(opentracing.Tags.HTTP_METHOD, ctx.method); | ||
span.setTag(opentracing.Tags.HTTP_URL, ctx.url); | ||
span.log({ "request": msg }); | ||
@@ -203,8 +181,8 @@ span.finish(); | ||
if (ctx.status >= 400) { | ||
throw new koatty_exception.Exception('', 1, ctx.status); | ||
throw new koatty_exception.Exception(ctx.message, 1, ctx.status); | ||
} | ||
return null; | ||
return respond(ctx); | ||
} | ||
catch (err) { | ||
return catcher(ctx, span, err, ext.globalErrorHandler); | ||
return catcher(ctx, err, span, ext.globalErrorHandler); | ||
} | ||
@@ -215,10 +193,70 @@ finally { | ||
} | ||
/** | ||
* Response helper. | ||
* A copy of koa respond: https://github.com/koajs/koa/blob/aa816ca523e0f7f3ca7623163762a2e63a7b0ee3/lib/application.js#L220 | ||
* | ||
* @param {KoattyContext} ctx | ||
* @returns {*} | ||
*/ | ||
function respond(ctx) { | ||
// allow bypassing koa | ||
if (false === ctx.respond) | ||
return; | ||
if (!ctx.writable) | ||
return; | ||
const res = ctx.res; | ||
let body = ctx.body; | ||
const code = ctx.status; | ||
// ignore body | ||
if (StatusEmpty.includes(code)) { | ||
// strip headers | ||
ctx.body = null; | ||
return res.end(); | ||
} | ||
if ('HEAD' === ctx.method) { | ||
if (!res.headersSent && !ctx.response.has('Content-Length')) { | ||
const { length } = ctx.response; | ||
if (Number.isInteger(length)) | ||
ctx.length = length; | ||
} | ||
return res.end(); | ||
} | ||
// status body | ||
if (null == body) { | ||
if (ctx.response._explicitNullBody) { | ||
ctx.response.remove('Content-Type'); | ||
ctx.response.remove('Transfer-Encoding'); | ||
return res.end(); | ||
} | ||
if (ctx.req.httpVersionMajor >= 2) { | ||
body = String(code); | ||
} | ||
else { | ||
body = ctx.message || String(code); | ||
} | ||
if (!res.headersSent) { | ||
ctx.type = 'text'; | ||
ctx.length = Buffer.byteLength(body); | ||
} | ||
return res.end(body); | ||
} | ||
// status | ||
if (code === 404) { | ||
ctx.status = 200; | ||
} | ||
// responses | ||
if (Buffer.isBuffer(body)) | ||
return res.end(body); | ||
if ('string' === typeof body) | ||
return res.end(body); | ||
if (body instanceof stream.Stream) | ||
return body.pipe(res); | ||
// body: json | ||
body = JSON.stringify(body); | ||
if (!res.headersSent) { | ||
ctx.length = Buffer.byteLength(body); | ||
} | ||
res.end(body); | ||
} | ||
/* | ||
* @Description: | ||
* @Usage: | ||
* @Author: richen | ||
* @Date: 2021-11-19 00:23:06 | ||
* @LastEditTime: 2024-01-16 08:09:29 | ||
*/ | ||
/** | ||
@@ -232,6 +270,2 @@ * gRPCHandler | ||
const timeout = ext.timeout || 10000; | ||
// set ctx start time | ||
Helper__namespace.define(ctx, 'startTime', Date.now()); | ||
// originalPath | ||
Helper__namespace.define(ctx, 'originalPath', ctx.path); | ||
// Encoding | ||
@@ -250,5 +284,8 @@ ctx.encoding = ext.encoding; | ||
const status = koatty_exception.StatusCodeConvert(ctx.status); | ||
const msg = `{"action":"${ctx.protocol}","code":"${status}","startTime":"${ctx.startTime}","duration":"${(now - ctx.startTime) || 0}","requestId":"${ext.requestId}","endTime":"${now}","path":"${ctx.originalPath}"}`; | ||
const msg = `{"action":"${ctx.protocol}","code":"${status}","startTime":"${ctx.startTime}","duration":"${(now - ctx.startTime) || 0}","requestId":"${ctx.requestId}","endTime":"${now}","path":"${ctx.originalPath}"}`; | ||
koatty_logger.DefaultLogger[(status > 0 ? 'Error' : 'Info')](msg); | ||
if (span) { | ||
span.setTag(opentracing.Tags.HTTP_STATUS_CODE, status); | ||
span.setTag(opentracing.Tags.HTTP_METHOD, ctx.method); | ||
span.setTag(opentracing.Tags.HTTP_URL, ctx.url); | ||
span.log({ "request": msg }); | ||
@@ -276,3 +313,3 @@ span.finish(); | ||
if (ctx.status >= 400) { | ||
throw new koatty_exception.Exception('', 0, ctx.status); | ||
throw new koatty_exception.Exception(ctx.message, 0, ctx.status); | ||
} | ||
@@ -283,3 +320,3 @@ ctx.rpc.callback(null, ctx.body); | ||
catch (err) { | ||
return catcher(ctx, span, err, ext.globalErrorHandler); | ||
return catcher(ctx, err, span, ext.globalErrorHandler); | ||
} | ||
@@ -297,3 +334,3 @@ finally { | ||
* @Date: 2021-11-19 00:24:43 | ||
* @LastEditTime: 2024-01-14 11:32:12 | ||
* @LastEditTime: 2024-01-24 11:01:56 | ||
*/ | ||
@@ -308,8 +345,2 @@ /** | ||
const timeout = ext.timeout || 10000; | ||
// set ctx start time | ||
Helper__namespace.define(ctx, 'startTime', Date.now()); | ||
// http version | ||
Helper__namespace.define(ctx, 'version', ctx.req.httpVersion); | ||
// originalPath | ||
Helper__namespace.define(ctx, 'originalPath', ctx.path); | ||
// Encoding | ||
@@ -329,5 +360,8 @@ ctx.encoding = ext.encoding; | ||
const now = Date.now(); | ||
const msg = `{"action":"${ctx.protocol}","code":"${ctx.status}","startTime":"${ctx.startTime}","duration":"${(now - ctx.startTime) || 0}","requestId":"${ext.requestId}","endTime":"${now}","path":"${ctx.originalPath || '/'}"}`; | ||
const msg = `{"action":"${ctx.protocol}","code":"${ctx.status}","startTime":"${ctx.startTime}","duration":"${(now - ctx.startTime) || 0}","requestId":"${ctx.requestId}","endTime":"${now}","path":"${ctx.originalPath || '/'}"}`; | ||
koatty_logger.DefaultLogger[(ctx.status >= 400 ? 'Error' : 'Info')](msg); | ||
if (span) { | ||
span.setTag(opentracing.Tags.HTTP_STATUS_CODE, ctx.status); | ||
span.setTag(opentracing.Tags.HTTP_METHOD, ctx.method); | ||
span.setTag(opentracing.Tags.HTTP_URL, ctx.url); | ||
span.log({ "request": msg }); | ||
@@ -361,3 +395,3 @@ span.finish(); | ||
if (ctx.status >= 400) { | ||
throw new koatty_exception.Exception("", 1, ctx.status); | ||
throw new koatty_exception.Exception(ctx.message, 1, ctx.status); | ||
} | ||
@@ -368,3 +402,3 @@ ctx.websocket.send(util.inspect(ctx.body || ''), null); | ||
catch (err) { | ||
return catcher(ctx, span, err, ext.globalErrorHandler); | ||
return catcher(ctx, err, span, ext.globalErrorHandler); | ||
} | ||
@@ -377,72 +411,2 @@ finally { | ||
// StatusEmpty | ||
const StatusEmpty = [204, 205, 304]; | ||
/** | ||
* Response helper. | ||
* A copy of koa respond: https://github.com/koajs/koa/blob/aa816ca523e0f7f3ca7623163762a2e63a7b0ee3/lib/application.js#L220 | ||
* | ||
* @param {KoattyContext} ctx | ||
* @returns {*} | ||
*/ | ||
function respond(ctx) { | ||
// allow bypassing koa | ||
if (false === ctx.respond) | ||
return; | ||
if (!ctx.writable) | ||
return; | ||
const res = ctx.res; | ||
let body = ctx.body; | ||
const code = ctx.status; | ||
// ignore body | ||
if (StatusEmpty.includes(code)) { | ||
// strip headers | ||
ctx.body = null; | ||
return res.end(); | ||
} | ||
if ('HEAD' === ctx.method) { | ||
if (!res.headersSent && !ctx.response.has('Content-Length')) { | ||
const { length } = ctx.response; | ||
if (Number.isInteger(length)) | ||
ctx.length = length; | ||
} | ||
return res.end(); | ||
} | ||
// status body | ||
if (null == body) { | ||
if (ctx.response._explicitNullBody) { | ||
ctx.response.remove('Content-Type'); | ||
ctx.response.remove('Transfer-Encoding'); | ||
return res.end(); | ||
} | ||
if (ctx.req.httpVersionMajor >= 2) { | ||
body = String(code); | ||
} | ||
else { | ||
body = ctx.message || String(code); | ||
} | ||
if (!res.headersSent) { | ||
ctx.type = 'text'; | ||
ctx.length = Buffer.byteLength(body); | ||
} | ||
return res.end(body); | ||
} | ||
// status | ||
if (code === 404) { | ||
ctx.status = 200; | ||
} | ||
// responses | ||
if (Buffer.isBuffer(body)) | ||
return res.end(body); | ||
if ('string' === typeof body) | ||
return res.end(body); | ||
if (body instanceof stream.Stream) | ||
return body.pipe(res); | ||
// body: json | ||
body = JSON.stringify(body); | ||
if (!res.headersSent) { | ||
ctx.length = Buffer.byteLength(body); | ||
} | ||
res.end(body); | ||
} | ||
/* | ||
@@ -452,3 +416,3 @@ * @Author: richen | ||
* @LastEditors: Please set LastEditors | ||
* @LastEditTime: 2024-01-21 12:34:46 | ||
* @LastEditTime: 2024-01-24 10:42:07 | ||
* @License: BSD (3-Clause) | ||
@@ -475,3 +439,3 @@ * @Copyright (c) - <richenlin(at)gmail.com> | ||
// metadata | ||
ctx.setMetaData(options.RequestIdName, ext.requestId); | ||
ctx.setMetaData(options.RequestIdName, ctx.requestId); | ||
// protocol handler | ||
@@ -482,5 +446,4 @@ switch (ctx.protocol) { | ||
ctx.respond = false; | ||
ctx.rpc.call.metadata.set(options.RequestIdName, ext.requestId); | ||
await gRPCHandler(ctx, next, ext); | ||
break; | ||
ctx.rpc.call.metadata.set(options.RequestIdName, ctx.requestId); | ||
return gRPCHandler(ctx, next, ext); | ||
case "ws": | ||
@@ -490,12 +453,9 @@ case "wss": | ||
ctx.respond = false; | ||
ctx.set(options.RequestIdHeaderName, ext.requestId); | ||
await wsHandler(ctx, next, ext); | ||
break; | ||
ctx.set(options.RequestIdHeaderName, ctx.requestId); | ||
return wsHandler(ctx, next, ext); | ||
default: | ||
// response header | ||
ctx.set(options.RequestIdHeaderName, ext.requestId); | ||
await httpHandler(ctx, next, ext); | ||
break; | ||
ctx.set(options.RequestIdHeaderName, ctx.requestId); | ||
return httpHandler(ctx, next, ext); | ||
} | ||
return respond(ctx); | ||
}; | ||
@@ -522,2 +482,6 @@ /** | ||
return async (ctx, next) => { | ||
// set ctx start time | ||
koatty_lib.Helper.define(ctx, 'startTime', Date.now()); | ||
// originalPath | ||
koatty_lib.Helper.define(ctx, 'originalPath', ctx.path); | ||
// server terminated | ||
@@ -535,2 +499,4 @@ let terminated = false; | ||
case "grpc": | ||
// http version | ||
koatty_lib.Helper.define(ctx, 'version', "2.0"); | ||
const request = ctx.getMetaData("_body")[0] || {}; | ||
@@ -541,2 +507,4 @@ requestId = `${ctx.getMetaData(options.RequestIdName)[0]}` || | ||
default: | ||
// http version | ||
koatty_lib.Helper.define(ctx, 'version', ctx.req.httpVersion); | ||
const requestIdHeaderName = options.RequestIdHeaderName.toLowerCase(); | ||
@@ -548,2 +516,3 @@ requestId = ctx.headers[requestIdHeaderName] || | ||
requestId = requestId || getTraceId(options); | ||
koatty_lib.Helper.define(ctx, 'requestId', requestId); | ||
let span; | ||
@@ -564,2 +533,3 @@ // opten trace | ||
const ext = { | ||
debug: app.appDebug, | ||
timeout: options.Timeout, | ||
@@ -592,3 +562,3 @@ encoding: options.Encoding, | ||
let rid; | ||
if (Helper.Helper.isFunction(options.IdFactory)) { | ||
if (koatty_lib.Helper.isFunction(options.IdFactory)) { | ||
rid = options?.IdFactory(); | ||
@@ -595,0 +565,0 @@ } |
{ | ||
"name": "koatty_trace", | ||
"version": "1.12.0", | ||
"version": "1.12.1", | ||
"description": "Full link tracking and error interception for koatty.", | ||
@@ -91,3 +91,3 @@ "scripts": { | ||
"koatty_core": "^1.x.x", | ||
"koatty_exception": "^1.x.x", | ||
"koatty_exception": "^1.3.2-0", | ||
"koatty_lib": "^1.x.x", | ||
@@ -94,0 +94,0 @@ "koatty_logger": "^2.x.x", |
# koatty_trace | ||
Full link tracking and error interception for koatty. |
{ | ||
"name": "koatty_trace", | ||
"version": "1.12.0", | ||
"version": "1.12.1", | ||
"description": "Full link tracking and error interception for koatty.", | ||
@@ -91,3 +91,3 @@ "scripts": { | ||
"koatty_core": "^1.x.x", | ||
"koatty_exception": "^1.x.x", | ||
"koatty_exception": "^1.3.2-0", | ||
"koatty_lib": "^1.x.x", | ||
@@ -94,0 +94,0 @@ "koatty_logger": "^2.x.x", |
# koatty_trace | ||
Full link tracking and error interception for koatty. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53800
1162
Updatedkoatty_exception@^1.3.2-0