rian 0.3.5 → 0.3.7
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/async.js +1 -1
- package/async.mjs +1 -1
- package/exporter.console.js +1 -0
- package/exporter.console.mjs +1 -0
- package/index.d.ts +2 -4
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +9 -4
- package/readme.md +66 -27
package/async.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const e = require('node:async_hooks');const { measure:t } = require('rian/utils');const { make:n, parse:r, SAMPLED_FLAG:o } = require('tctx');const { is_sampled:a } = require('tctx');var s={};function
|
1
|
+
const e = require('node:async_hooks');const { measure:t } = require('rian/utils');const { make:n, parse:r, SAMPLED_FLAG:o } = require('tctx');const { is_sampled:a } = require('tctx');var s={};function c(e,t={}){s={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.7"}}var l=new Set,p=new WeakMap;async function u(e){let t=[],n=new Map;for(let[e,r]of l){let o;if(n.has(r)?o=n.get(r).spans:n.set(r,{scope:r,spans:o=[]}),o.push(e),p.has(r)){let e=p.get(r);t.push(...e),e.clear()}}return l.clear(),t.length&&await Promise.all(t),e({resource:s,scopeSpans:n.values()})}function i(e,t){return a(t)}var f=new e.AsyncLocalStorage;function m(){let e=f.getStore()?.[1];if(null==e)throw new Error("no current span");return e}function d(e,a){let s=f.getStore();if(!s)throw Error("no current tracer");let c=s[0],u=c.scope,i=s[1],m=c.sampler,g=null!=a?"string"==typeof a?r(a):a:i?.traceparent,w=g?g.child():n(),h="boolean"!=typeof m?m(e,w,u):m;h?w.flags|=o:w.flags&=~o;let k={id:w,parent:g,start:c.clock.now(),name:e,events:[],context:{}};h&&l.add([k,u]);let v=e=>f.run([c,v],t,v,e);v.traceparent=w,v.span=e=>f.run([c,v],d,e),v.set_context=e=>{"function"!=typeof e?Object.assign(k.context,e):k.context=e(k.context)},v.add_event=(e,t)=>{k.events.push({name:e,timestamp:c.clock.now(),attributes:t||{}})},v.end=()=>{null==k.end&&(k.end=c.clock.now())};let x=p.get(u);return v.__add_promise=e=>{x.add(e),e.then((()=>x.delete(e)))},v}function g(e,t){let n={name:e},r={scope:n,sampler:t?.sampler??i,clock:t?.clock??Date};return p.set(n,new Set),function(e){let t=f.getStore();return f.run([r,t?.[1]||null],e)}}exports.configure=c;exports.currentSpan=m;exports.report=u;exports.span=d;exports.tracer=g;
|
package/async.mjs
CHANGED
@@ -1 +1 @@
|
|
1
|
-
import*as e from"node:async_hooks";import{measure as t}from"rian/utils";import{make as n,parse as r,SAMPLED_FLAG as o}from"tctx";import{is_sampled as a}from"tctx";var s={};function
|
1
|
+
import*as e from"node:async_hooks";import{measure as t}from"rian/utils";import{make as n,parse as r,SAMPLED_FLAG as o}from"tctx";import{is_sampled as a}from"tctx";var s={};function c(e,t={}){s={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.7"}}var l=new Set,p=new WeakMap;async function u(e){let t=[],n=new Map;for(let[e,r]of l){let o;if(n.has(r)?o=n.get(r).spans:n.set(r,{scope:r,spans:o=[]}),o.push(e),p.has(r)){let e=p.get(r);t.push(...e),e.clear()}}return l.clear(),t.length&&await Promise.all(t),e({resource:s,scopeSpans:n.values()})}function i(e,t){return a(t)}var f=new e.AsyncLocalStorage;function m(){let e=f.getStore()?.[1];if(null==e)throw new Error("no current span");return e}function d(e,a){let s=f.getStore();if(!s)throw Error("no current tracer");let c=s[0],u=c.scope,i=s[1],m=c.sampler,g=null!=a?"string"==typeof a?r(a):a:i?.traceparent,w=g?g.child():n(),h="boolean"!=typeof m?m(e,w,u):m;h?w.flags|=o:w.flags&=~o;let k={id:w,parent:g,start:c.clock.now(),name:e,events:[],context:{}};h&&l.add([k,u]);let v=e=>f.run([c,v],t,v,e);v.traceparent=w,v.span=e=>f.run([c,v],d,e),v.set_context=e=>{"function"!=typeof e?Object.assign(k.context,e):k.context=e(k.context)},v.add_event=(e,t)=>{k.events.push({name:e,timestamp:c.clock.now(),attributes:t||{}})},v.end=()=>{null==k.end&&(k.end=c.clock.now())};let x=p.get(u);return v.__add_promise=e=>{x.add(e),e.then((()=>x.delete(e)))},v}function g(e,t){let n={name:e},r={scope:n,sampler:t?.sampler??i,clock:t?.clock??Date};return p.set(n,new Set),function(e){let t=f.getStore();return f.run([r,t?.[1]||null],e)}}export{c as configure,m as currentSpan,u as report,d as span,g as tracer};
|
@@ -0,0 +1 @@
|
|
1
|
+
function t(t=120){if(t<24)throw new Error("max_cols must be at least 24");return function(e){console.log(function(t,e=""){let a,n,r=Object.keys(t),l=0;for(n=0;a=r[n++];l=Math.max(l,a.length));let o="";for(n=0;a=r[n++];o+=e+a.padStart(l)+": "+t[a]+"\n");return o}(e.resource)+"─".repeat(t)),t-=2;for(let a of e.scopeSpans){let e=a.spans;if(!e.length)return;let n,r,o=0,s=e[0].start;for(r=0;n=a.spans[r++];)o=Math.max(o,n.end??n.start),s=Math.min(s,n.start);let h=o-s,i=l(h),p=i.length,f=p+2,u=Math.ceil(2/3*(t-f)),c=u-4,m=t-f-u,d=Math.ceil(c/2),g=l(h/2),M=Math.ceil(g.length/2),S="";for(S+="╭─ ",S+=a.scope.name,S+="\n",S+="│ ",S+="╭".padStart(f),S+="─".repeat(u),S+="╮\n",r=0;n=a.spans[r++];){let t=n.start-s,e=(n.end??o)-s,a=Math.ceil(t/h*c),r=Math.ceil(e/h*c);S+="│ ",S+=l(e-t).padStart(p),S+=" │",S+=" ".repeat(a+1),S+="┣",S+=(n.end?"━":"╍").repeat(r-a),S+="┫",S+=" ".repeat(u-r-3),S+="│◗ ",S+=n.name.length+4>m?n.name.substring(0,m-4)+"…":n.name,S+="\n"}S+="│ ",S+="╰".padStart(f),S+="┼",S+="┴".repeat(d-2),S+="┼",S+="┴".repeat(u-d-1),S+="┼",S+="╯\n",S+="│ ",S+="0 ms".padStart(p+2+4),S+=g.padStart(d+M-4),S+=i.padStart(c-d+2-(M+4)+i.length),S+="\n│\n",S+="│ ";let $=l(h/c),x=Math.max($.length,i.length);S+=n=`one └┘ unit is less than: ${$}\n`,S+="│ ",S+=`total time: ${i.padStart(x)}`.padStart(n.length-1),S+="\n╰─",console.log(S)}}}var e=6e4,a=60*e,n=1e3;function r(t){return t%1==0?String(t):t.toFixed(3)}function l(t){if(t<0)return"0 ms";if(t<n)return`${r(t)} ms`;if(t<e)return`${r(t/n)} s`;if(t<a){return`${Math.floor(t/e)} m ${Math.floor(t%e/n)} s ${r(t%n)} ms`}return"> 1hr"}exports.exporter=t;
|
@@ -0,0 +1 @@
|
|
1
|
+
function t(t=120){if(t<24)throw new Error("max_cols must be at least 24");return function(e){console.log(function(t,e=""){let a,n,r=Object.keys(t),l=0;for(n=0;a=r[n++];l=Math.max(l,a.length));let o="";for(n=0;a=r[n++];o+=e+a.padStart(l)+": "+t[a]+"\n");return o}(e.resource)+"─".repeat(t)),t-=2;for(let a of e.scopeSpans){let e=a.spans;if(!e.length)return;let n,r,o=0,s=e[0].start;for(r=0;n=a.spans[r++];)o=Math.max(o,n.end??n.start),s=Math.min(s,n.start);let h=o-s,i=l(h),p=i.length,f=p+2,u=Math.ceil(2/3*(t-f)),c=u-4,m=t-f-u,d=Math.ceil(c/2),g=l(h/2),M=Math.ceil(g.length/2),S="";for(S+="╭─ ",S+=a.scope.name,S+="\n",S+="│ ",S+="╭".padStart(f),S+="─".repeat(u),S+="╮\n",r=0;n=a.spans[r++];){let t=n.start-s,e=(n.end??o)-s,a=Math.ceil(t/h*c),r=Math.ceil(e/h*c);S+="│ ",S+=l(e-t).padStart(p),S+=" │",S+=" ".repeat(a+1),S+="┣",S+=(n.end?"━":"╍").repeat(r-a),S+="┫",S+=" ".repeat(u-r-3),S+="│◗ ",S+=n.name.length+4>m?n.name.substring(0,m-4)+"…":n.name,S+="\n"}S+="│ ",S+="╰".padStart(f),S+="┼",S+="┴".repeat(d-2),S+="┼",S+="┴".repeat(u-d-1),S+="┼",S+="╯\n",S+="│ ",S+="0 ms".padStart(p+2+4),S+=g.padStart(d+M-4),S+=i.padStart(c-d+2-(M+4)+i.length),S+="\n│\n",S+="│ ";let $=l(h/c),x=Math.max($.length,i.length);S+=n=`one └┘ unit is less than: ${$}\n`,S+="│ ",S+=`total time: ${i.padStart(x)}`.padStart(n.length-1),S+="\n╰─",console.log(S)}}}var e=6e4,a=60*e,n=1e3;function r(t){return t%1==0?String(t):t.toFixed(3)}function l(t){if(t<0)return"0 ms";if(t<n)return`${r(t)} ms`;if(t<e)return`${r(t/n)} s`;if(t<a){return`${Math.floor(t/e)} m ${Math.floor(t%e/n)} s ${r(t%n)} ms`}return"> 1hr"}export{t as exporter};
|
package/index.d.ts
CHANGED
@@ -217,9 +217,7 @@ export function tracer(name: string, options?: Options): Tracer;
|
|
217
217
|
/**
|
218
218
|
* Awaits all active promises, and then calls the {@link Options.exporter|exporter}. Passing all collected spans.
|
219
219
|
*/
|
220
|
-
export
|
221
|
-
exporter: T,
|
222
|
-
): Promise<ReturnType<T>>;
|
220
|
+
export function report<T extends Exporter>(exporter: T): Promise<ReturnType<T>>;
|
223
221
|
|
224
222
|
/**
|
225
223
|
* Calling this method will set the resource attributes for this runtime. This is useful for things like:
|
@@ -237,7 +235,7 @@ export async function report<T extends Exporter>(
|
|
237
235
|
* configure('my-service', { 'deployment.environment': 'production', 'k8s.namespace.name': 'default' });
|
238
236
|
* ```
|
239
237
|
*/
|
240
|
-
export function configure(name: string, attributes
|
238
|
+
export function configure(name: string, attributes?: Context): void;
|
241
239
|
|
242
240
|
/**
|
243
241
|
* Provinding a clock allows you to control the time of the span.
|
package/index.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const { measure:e } = require('rian/utils');const { make:t, parse:n, SAMPLED_FLAG:a } = require('tctx');const { is_sampled:s } = require('tctx');var o={};function r(e,t={}){o={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.
|
1
|
+
const { measure:e } = require('rian/utils');const { make:t, parse:n, SAMPLED_FLAG:a } = require('tctx');const { is_sampled:s } = require('tctx');var o={};function r(e,t={}){o={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.7"}}var l=new Set,i=new WeakMap;async function c(e){let t=[],n=new Map;for(let[e,a]of l){let s;if(n.has(a)?s=n.get(a).spans:n.set(a,{scope:a,spans:s=[]}),s.push(e),i.has(a)){let e=i.get(a);t.push(...e),e.clear()}}return l.clear(),t.length&&await Promise.all(t),e({resource:o,scopeSpans:n.values()})}function p(e,t){return s(t)}function d(s,o){let r=o?.sampler??p,c=o?.clock??Date,d={name:s},m=new Set;i.set(d,m);let u=(s,o)=>{let i=null!=o?"string"==typeof o?n(o):o:void 0,p=i?i.child():t(),f="boolean"!=typeof r?r(s,p,d):r;f?p.flags|=a:p.flags&=~a;let v={id:p,parent:i,start:c.now(),name:s,events:[],context:{}};f&&l.add([v,d]);let h=t=>e(h,t);return h.traceparent=p,h.span=(e,t)=>u(e,t||p),h.set_context=e=>"function"==typeof e?void(v.context=e(v.context)):void Object.assign(v.context,e),h.add_event=(e,t)=>{v.events.push({name:e,timestamp:c.now(),attributes:t||{}})},h.end=()=>{null==v.end&&(v.end=c.now())},h.__add_promise=e=>{m.add(e),e.then((()=>m.delete(e)))},h};return{span:u}}exports.configure=r;exports.report=c;exports.tracer=d;
|
package/index.mjs
CHANGED
@@ -1 +1 @@
|
|
1
|
-
import{measure as e}from"rian/utils";import{make as t,parse as n,SAMPLED_FLAG as a}from"tctx";import{is_sampled as s}from"tctx";var o={};function r(e,t={}){o={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.
|
1
|
+
import{measure as e}from"rian/utils";import{make as t,parse as n,SAMPLED_FLAG as a}from"tctx";import{is_sampled as s}from"tctx";var o={};function r(e,t={}){o={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.7"}}var l=new Set,i=new WeakMap;async function c(e){let t=[],n=new Map;for(let[e,a]of l){let s;if(n.has(a)?s=n.get(a).spans:n.set(a,{scope:a,spans:s=[]}),s.push(e),i.has(a)){let e=i.get(a);t.push(...e),e.clear()}}return l.clear(),t.length&&await Promise.all(t),e({resource:o,scopeSpans:n.values()})}function p(e,t){return s(t)}function d(s,o){let r=o?.sampler??p,c=o?.clock??Date,d={name:s},m=new Set;i.set(d,m);let u=(s,o)=>{let i=null!=o?"string"==typeof o?n(o):o:void 0,p=i?i.child():t(),f="boolean"!=typeof r?r(s,p,d):r;f?p.flags|=a:p.flags&=~a;let v={id:p,parent:i,start:c.now(),name:s,events:[],context:{}};f&&l.add([v,d]);let h=t=>e(h,t);return h.traceparent=p,h.span=(e,t)=>u(e,t||p),h.set_context=e=>"function"==typeof e?void(v.context=e(v.context)):void Object.assign(v.context,e),h.add_event=(e,t)=>{v.events.push({name:e,timestamp:c.now(),attributes:t||{}})},h.end=()=>{null==v.end&&(v.end=c.now())},h.__add_promise=e=>{m.add(e),e.then((()=>m.delete(e)))},h};return{span:u}}export{r as configure,c as report,d as tracer};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "rian",
|
3
|
-
"version": "0.3.
|
3
|
+
"version": "0.3.7",
|
4
4
|
"description": "Effective tracing for the edge and origins",
|
5
5
|
"keywords": [
|
6
6
|
"opentelemetry",
|
@@ -40,6 +40,11 @@
|
|
40
40
|
"import": "./exporter.zipkin.mjs",
|
41
41
|
"require": "./exporter.zipkin.js"
|
42
42
|
},
|
43
|
+
"./exporter.console": {
|
44
|
+
"types": "./exporter.console.d.ts",
|
45
|
+
"import": "./exporter.console.mjs",
|
46
|
+
"require": "./exporter.console.js"
|
47
|
+
},
|
43
48
|
"./utils": {
|
44
49
|
"types": "./utils.d.ts",
|
45
50
|
"import": "./utils.mjs",
|
@@ -62,7 +67,6 @@
|
|
62
67
|
"bench": "node -r tsm bench/index.ts",
|
63
68
|
"build": "bundt --minify",
|
64
69
|
"format": "prettier --write \"{*,{src,test}/**/*,examples/*/**,bench/*,.github/**/*}.+(ts|js|json|yml|md)\"",
|
65
|
-
"pretest": "pnpm run build",
|
66
70
|
"test": "uvu src \".test.ts$\" -r tsm",
|
67
71
|
"typecheck": "tsc --noEmit"
|
68
72
|
},
|
@@ -74,11 +78,12 @@
|
|
74
78
|
"devDependencies": {
|
75
79
|
"@marais/prettier": "0.0.4",
|
76
80
|
"@marais/tsconfig": "0.0.4",
|
81
|
+
"@types/node": "20.4.5",
|
77
82
|
"bundt": "2.0.0-next.5",
|
78
83
|
"nanospy": "1.0.0",
|
79
|
-
"prettier": "
|
84
|
+
"prettier": "3.0.0",
|
80
85
|
"tsm": "2.3.0",
|
81
|
-
"typescript": "5.1.
|
86
|
+
"typescript": "5.1.6",
|
82
87
|
"uvu": "0.5.4"
|
83
88
|
},
|
84
89
|
"volta": {
|
package/readme.md
CHANGED
@@ -1,24 +1,36 @@
|
|
1
|
-
<div align="
|
1
|
+
<div align="left">
|
2
|
+
|
3
|
+
<samp>
|
4
|
+
|
2
5
|
<img src="files/logo-light.svg#gh-light-mode-only" alt="rian light mode logo" width="200px">
|
3
6
|
<img src="files/logo-dark.svg#gh-dark-mode-only" alt="rian dark mode logo" width="200px">
|
4
|
-
<br />
|
5
|
-
<br />
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
</samp>
|
9
|
+
|
10
|
+
**A utility to simplify your tracing**
|
11
|
+
|
9
12
|
<a href="https://npm-stat.com/charts.html?package=rian">
|
10
|
-
|
13
|
+
<img src="https://badgen.net/npm/dm/rian?color=black&label=npm%20downloads" alt="js downloads">
|
11
14
|
</a>
|
12
|
-
<a href="https://
|
13
|
-
|
15
|
+
<a href="https://unpkg.com/rian/index.mjs">
|
16
|
+
<img src="https://img.badgesize.io/https://unpkg.com/rian/index.mjs?compression=gzip&label=gzip&color=black" alt="gzip size" />
|
14
17
|
</a>
|
15
|
-
<a href="https://
|
16
|
-
|
18
|
+
<a href="https://unpkg.com/rian/index.mjs">
|
19
|
+
<img src="https://img.badgesize.io/https://unpkg.com/rian/index.mjs?compression=brotli&label=brotli&color=black" alt="brotli size" />
|
17
20
|
</a>
|
18
|
-
</span>
|
19
21
|
|
20
|
-
<br
|
21
|
-
<br
|
22
|
+
<br>
|
23
|
+
<br>
|
24
|
+
|
25
|
+
<sup>
|
26
|
+
|
27
|
+
This is free to use software, but if you do like it, consisder supporting me ❤️
|
28
|
+
|
29
|
+
[](https://github.com/sponsors/maraisr)
|
30
|
+
[](https://www.buymeacoffee.com/marais)
|
31
|
+
|
32
|
+
</sup>
|
33
|
+
|
22
34
|
</div>
|
23
35
|
|
24
36
|
## ⚡ Features
|
@@ -40,8 +52,8 @@ import { configure, tracer, report } from 'rian';
|
|
40
52
|
import { exporter } from 'rian/exporter.otel.http';
|
41
53
|
|
42
54
|
// ~> configure the environment, all tracers will inherit this
|
43
|
-
configure('my-service' {
|
44
|
-
'service.version': 'DEV'
|
55
|
+
configure('my-service', {
|
56
|
+
'service.version': 'DEV',
|
45
57
|
});
|
46
58
|
|
47
59
|
// ~> create a tracer — typically "per request" or "per operation".
|
@@ -83,20 +95,47 @@ http.listen((req, executionCtx) => {
|
|
83
95
|
executionCtx.defer(() => report(otel_exporter));
|
84
96
|
return handler(req);
|
85
97
|
});
|
98
|
+
```
|
99
|
+
|
100
|
+
You only need to `report` in your application once somewhere. All spans are collected into the same "bucket".
|
86
101
|
|
87
|
-
|
88
|
-
And we end up with something like this in our reporting tool:
|
102
|
+
<details><summary>Example output</summary>
|
89
103
|
|
90
|
-
[
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
104
|
+
Using: [examples/basic.ts](examples/basic.ts)
|
105
|
+
|
106
|
+
```
|
107
|
+
╭─ basic
|
108
|
+
│ ╭─────────────────────────────────────────────────────────────────╮
|
109
|
+
│ 95 ms │ ┣━━━━━━━━━━┫ │◗ setup
|
110
|
+
│ 41 ms │ ┣━━━━┫ │◗ bootstrap
|
111
|
+
│ 32 ms │ ┣━━━┫ │◗ building
|
112
|
+
│ 59 ms │ ┣━━━━━┫ │◗ precompile
|
113
|
+
│ 80 ms │ ┣━━━━━━━━┫ │◗ verify
|
114
|
+
│ 75 ms │ ┣━━━━━━━┫ │◗ spawn thread
|
115
|
+
│ 371 ms │ ┣╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┫ │◗ doesnt finish
|
116
|
+
│ 347 ms │ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ │◗ running
|
117
|
+
│ 341 ms │ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ │◗ e2e
|
118
|
+
│ 38 ms │ ┣━━━┫ │◗ snapshot
|
119
|
+
│ 13 ms │ ┣━┫ │◗ url for page /my-product/sle…
|
120
|
+
│ ╰┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼╯
|
121
|
+
│ 0 ms 318.500 ms 637 ms
|
122
|
+
│
|
123
|
+
│ one └┘ unit is less than: 10.443 ms
|
124
|
+
│ total time: 637 ms
|
125
|
+
╰─
|
126
|
+
╭─ thread #1
|
127
|
+
│ ╭──────────────────────────────────────────────────────────────────╮
|
128
|
+
│ 20 ms │ ┣━━━━━━━━━━━━━━━━━━━━┫ │◗ setup
|
129
|
+
│ 63 ms │ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ │◗ bootstrap
|
130
|
+
│ ╰┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼╯
|
131
|
+
│ 0 ms 31.500 ms 63 ms
|
132
|
+
│
|
133
|
+
│ one └┘ unit is less than: 1.016 ms
|
134
|
+
│ total time: 63 ms
|
135
|
+
╰─
|
97
136
|
```
|
98
137
|
|
99
|
-
|
138
|
+
</details>
|
100
139
|
|
101
140
|
## 🔎 API
|
102
141
|
|
@@ -276,6 +315,6 @@ MIT © [Marais Rossouw](https://marais.io)
|
|
276
315
|
|
277
316
|
##### Disclaimer
|
278
317
|
|
279
|
-
<sup>- NewRelic is a registered trademark of https://newrelic.com/ and not affiliated with this project.</sup><br
|
280
|
-
<sup>- Datadog is a registered trademark of https://www.datadoghq.com/ and not affiliated with this project.</sup><br
|
318
|
+
<sup>- NewRelic is a registered trademark of https://newrelic.com/ and not affiliated with this project.</sup><br>
|
319
|
+
<sup>- Datadog is a registered trademark of https://www.datadoghq.com/ and not affiliated with this project.</sup><br>
|
281
320
|
<sup>- Lightstep is a registered trademark of https://lightstep.com/ and not affiliated with this project.</sup>
|