Skip to content

Commit

Permalink
0.1.9
Browse files Browse the repository at this point in the history
  • Loading branch information
ovx committed Feb 15, 2024
1 parent ec6206a commit 9098087
Show file tree
Hide file tree
Showing 27 changed files with 186 additions and 89 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@
"@typescript-eslint"
],
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-this-alias": "off"
}
}
3 changes: 3 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
npm test
npm run build
git add dist
4 changes: 3 additions & 1 deletion dist/inspector.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference types="node" />
import { Session } from './session.js';
import { ErrorsInstrument } from './instruments/errors.js';
import { EventsInstrument } from './instruments/events.js';
import { LogsInstrument } from './instruments/logs.js';
import { MetricsInstrument } from './instruments/metrics.js';
import { NetworkInstrument } from './instruments/network.js';
Expand All @@ -11,6 +12,7 @@ export declare class Inspector {
static defaultDashboards(): Dashboard[];
instruments: {
errors: ErrorsInstrument;
events: EventsInstrument;
logs: LogsInstrument;
metrics: MetricsInstrument;
network: NetworkInstrument;
Expand Down Expand Up @@ -38,5 +40,5 @@ export declare class Inspector {
activate(): void;
deactivate(): void;
createSession(init?: SessionInit): Session;
getInstrument(instrument: keyof typeof this.instruments): ErrorsInstrument | LogsInstrument | MetricsInstrument | NetworkInstrument | TracesInstrument;
getInstrument(instrument: keyof typeof this.instruments): ErrorsInstrument | EventsInstrument | LogsInstrument | MetricsInstrument | NetworkInstrument | TracesInstrument;
}
3 changes: 3 additions & 0 deletions dist/inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import os from 'node:os';
import proc from 'node:process';
import { Session } from './session.js';
import { ErrorsInstrument } from './instruments/errors.js';
import { EventsInstrument } from './instruments/events.js';
import { LogsInstrument } from './instruments/logs.js';
import { MetricsInstrument } from './instruments/metrics.js';
import { NetworkInstrument } from './instruments/network.js';
Expand Down Expand Up @@ -40,11 +41,13 @@ export class Inspector {
this.store = store;
this.instruments = {
errors: new ErrorsInstrument(store, instruments.errors),
events: new EventsInstrument(store, instruments.events),
logs: new LogsInstrument(store, instruments.logs),
metrics: new MetricsInstrument(store, instruments.metrics),
network: new NetworkInstrument(store, instruments.network),
traces: new TracesInstrument(store, instruments.traces),
};
this.activate();
}
activate() {
for (let key in this.instruments) {
Expand Down
2 changes: 1 addition & 1 deletion dist/instruments/errors.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { BaseInstrumentInit, ErrorsInstrumentValue, Query } from '../types.
import type { Store } from '@exotjs/measurements/types';
export declare class ErrorsInstrument extends BaseInstrument<ErrorsInstrumentValue> {
constructor(store: Store, init?: BaseInstrumentInit);
putToStore(time: number, label: string, value: any): Promise<void>;
putToStore(time: number, label: string, value: string): Promise<void>;
queryFromStore(query: Query): Promise<import("@exotjs/measurements/types").StoreQueryResult>;
getEntryLabel(value: ErrorsInstrumentValue): "client" | "server";
serializeValue(value: ErrorsInstrumentValue): string;
Expand Down
4 changes: 3 additions & 1 deletion dist/instruments/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ export class ErrorsInstrument extends BaseInstrument {
if (value instanceof Error) {
value = {
message: String(value.message),
modules: getModulesFromCallStack(value.stack?.split('\n') || []),
stack: value.stack,
};
}
if (value.modules === void 0 && value.stack) {
value.modules = getModulesFromCallStack(value.stack?.split('\n') || []);
}
return JSON.stringify(value);
}
}
10 changes: 10 additions & 0 deletions dist/instruments/events.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { BaseInstrument } from '../base.js';
import type { BaseInstrumentInit, EventsInstrumentValue, Query } from '../types.js';
import type { Store } from '@exotjs/measurements/types';
export declare class EventsInstrument extends BaseInstrument<EventsInstrumentValue> {
constructor(store: Store, init?: BaseInstrumentInit);
putToStore(time: number, label: string, value: string): Promise<void>;
queryFromStore(query: Query): Promise<import("@exotjs/measurements/types").StoreQueryResult>;
getEntryLabel(_value: EventsInstrumentValue): string;
serializeValue(value: EventsInstrumentValue): string;
}
19 changes: 19 additions & 0 deletions dist/instruments/events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { BaseInstrument } from '../base.js';
export class EventsInstrument extends BaseInstrument {
constructor(store, init = {}) {
const { disabled = false } = init;
super('events', store, disabled);
}
async putToStore(time, label, value) {
return this.store.listAdd(this.name, time, label, value);
}
async queryFromStore(query) {
return this.store.listQuery(this.name, query.startTime, query.endTime, query.limit);
}
getEntryLabel(_value) {
return '';
}
serializeValue(value) {
return JSON.stringify(value);
}
}
2 changes: 1 addition & 1 deletion dist/instruments/logs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Store } from '@exotjs/measurements/types';
import type { BaseInstrumentInit, Query } from '../types.js';
export declare class LogsInstrument extends BaseInstrument {
constructor(store: Store, init?: BaseInstrumentInit);
putToStore(time: number, label: string, value: any): Promise<void>;
putToStore(time: number, label: string, value: string): Promise<void>;
queryFromStore(query: Query): Promise<import("@exotjs/measurements/types").StoreQueryResult>;
activate(): boolean;
deactivate(): boolean;
Expand Down
5 changes: 3 additions & 2 deletions dist/instruments/logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class LogsInstrument extends BaseInstrument {
return super.deactivate();
}
mountStdout() {
// @ts-expect-error
// @ts-expect-error ignore argument type errors
process.stdout.write = (chunk, encoding, cb) => {
if (typeof chunk === 'string') {
this.push(this.stripAnsi(chunk), 'info');
Expand All @@ -32,6 +32,7 @@ export class LogsInstrument extends BaseInstrument {
process.stdout.write = originalStdoutWrite;
}
stripAnsi(str) {
return str.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
return str.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, // eslint-disable-line
'');
}
}
10 changes: 7 additions & 3 deletions dist/instruments/metrics.d.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { Store, StoreEntry } from '@exotjs/measurements/types';
import { BaseInstrument, SensorBase } from '../base.js';
import type { Dashboard, MetricsInstrumentInit, Query, TrackResponse } from '../types.js';
import type { Dashboard, MetricsInstrumentInit, Query } from '../types.js';
export declare class MetricsInstrument extends BaseInstrument {
#private;
dashboards: Dashboard[];
sensors: SensorBase[];
constructor(store: Store, init?: MetricsInstrumentInit);
trackResponse(response: TrackResponse): void;
push(data: Record<string, {
label?: string;
values: number[];
}[]>): Promise<void>;
activate(): boolean;
deactivate(): boolean;
putToStore(_time: number, _label: string, _value: string): Promise<void>;
query(query: Query & {
keys: string[];
}): Promise<{
entries: StoreEntry[];
hasMore: boolean;
}>;
subscribe(fn: (time: number, label: string, value: any) => void, options: {
subscribe(fn: (time: number, label: string, value: unknown) => void, options: {
interval?: number;
keys?: string[];
startTime?: number;
Expand Down
25 changes: 8 additions & 17 deletions dist/instruments/metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,11 @@ export class MetricsInstrument extends BaseInstrument {
store,
});
}
trackResponse(response) {
const status = String(response.status).slice(0, 1) + 'xx';
this.#measurements.push({
'response:latency': [
{
values: [response.duration],
},
],
[`response:${status}`]: [
{
values: [1],
},
],
});
async push(data) {
return this.#measurements.push(data);
}
activate() {
for (let [key, config] of this.#measurements.measurements) {
for (const [key, config] of this.#measurements.measurements) {
if (config.sensor) {
const cls = this.#getSensor(config.sensor);
const sensor = new cls(key, config.interval);
Expand All @@ -53,12 +41,15 @@ export class MetricsInstrument extends BaseInstrument {
return super.activate();
}
deactivate() {
for (let sensor of this.sensors) {
for (const sensor of this.sensors) {
sensor.destroy();
}
this.sensors = [];
return super.deactivate();
}
async putToStore(_time, _label, _value) {
// noop
}
async query(query) {
const result = await this.#measurements.export({
...query,
Expand Down Expand Up @@ -107,7 +98,7 @@ export class MetricsInstrument extends BaseInstrument {
}
#getMeasurementsFromDashboards(dashboards) {
return dashboards.reduce((acc, dashboard) => {
for (let measurement of dashboard.measurements) {
for (const measurement of dashboard.measurements) {
if (!acc.find(({ key }) => key === measurement.key)) {
acc.push({
interval: measurement.interval || 10000,
Expand Down
2 changes: 1 addition & 1 deletion dist/instruments/network.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Store } from '@exotjs/measurements/types';
export declare class NetworkInstrument extends BaseInstrument {
#private;
constructor(store: Store, init?: NetworkInstrumentInit);
putToStore(time: number, label: string, value: any): Promise<void>;
putToStore(time: number, label: string, value: string): Promise<void>;
queryFromStore(query: Query): Promise<import("@exotjs/measurements/types").StoreQueryResult>;
getEntryLabel(value: NetworkRequest): string;
serializeValue(value: NetworkRequest): string;
Expand Down
9 changes: 1 addition & 8 deletions dist/instruments/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,13 @@ export class NetworkInstrument extends BaseInstrument {
const _write = req.write;
req.write = (chunk, ...args) => {
onChunk(chunk);
// @ts-expect-error
return _write.call(req, chunk, ...args);
};
req.end = (chunk, ...args) => {
if (chunk) {
if (chunk && typeof chunk !== 'function') {
onChunk(chunk);
}
if (target.body) {
target.body = target.body;
}
resolve(void 0);
// @ts-expect-error
return _end.call(req, chunk, ...args);
};
});
Expand Down Expand Up @@ -201,7 +196,6 @@ export class NetworkInstrument extends BaseInstrument {
const createInterceptor = (makeRequest, initiator) => {
return function httpInterceptor(...args) {
if (!self.active) {
// @ts-expect-error
return makeRequest(...args);
}
const stack = getCallStack();
Expand All @@ -224,7 +218,6 @@ export class NetworkInstrument extends BaseInstrument {
stack,
start: Math.floor((performance.timeOrigin + start) * 100) / 100,
};
// @ts-expect-error
const req = makeRequest(...args);
if (self.#readBody) {
self.#readHttpRequestBody(req, request.request);
Expand Down
2 changes: 1 addition & 1 deletion dist/instruments/traces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export declare class TracesInstrument extends BaseInstrument {
get endSpan(): (span: TraceSpan) => TraceSpan | undefined;
get startSpan(): (name: string, parent?: TraceSpan | undefined) => TraceSpan;
get trace(): <T>(name: string, fn: (ctx: import("@exotjs/trace/types").TraceContext) => T | Promise<T>, options?: import("@exotjs/trace/types").TraceOptions | undefined) => T | Promise<T>;
putToStore(time: number, label: string, value: any): Promise<void>;
putToStore(time: number, label: string, value: string): Promise<void>;
queryFromStore(query: Query): Promise<import("@exotjs/measurements/types").StoreQueryResult>;
getEntryLabel(value: TraceSpan): string;
getEntryTime(entry: TraceSpan): number;
Expand Down
10 changes: 8 additions & 2 deletions dist/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export interface SessionInit {
remoteAddress?: string;
user?: string;
}
export type InspectorInstruments = 'errors' | 'logs' | 'metrics' | 'network' | 'traces';
export type InspectorInstruments = 'errors' | 'events' | 'logs' | 'metrics' | 'network' | 'traces';
export interface Dashboard {
measurements: {
interval?: number;
Expand All @@ -109,6 +109,7 @@ export interface NetworkInstrumentInit extends BaseInstrumentInit {
}
export interface InspectorInitInstruments {
errors?: BaseInstrumentInit;
events?: BaseInstrumentInit;
logs?: BaseInstrumentInit;
metrics?: MetricsInstrumentInit;
network?: NetworkInstrumentInit;
Expand All @@ -119,8 +120,13 @@ export interface InspectorInit {
store: Store;
}
export interface ErrorsInstrumentValue {
attributes?: Record<string, any>;
message: string;
modules?: string[];
server?: boolean;
stack: string;
stack?: string;
}
export interface EventsInstrumentValue {
attributes?: Record<string, any>;
name: string;
}
26 changes: 23 additions & 3 deletions example/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,18 @@ server.on('request', async (req, res) => {
const path = getPath(req.url || '/');

res.on('close', () => {
inspector.instruments.metrics.trackResponse({
status: res.statusCode,
duration: performance.now() - start,
const status = String(res.statusCode).slice(0, 1) + 'xx';
inspector.instruments.metrics.push({
'response:latency': [
{
values: [performance.now() - start],
},
],
[`response:${status}`]: [
{
values: [1],
},
],
});
});

Expand Down Expand Up @@ -106,6 +115,17 @@ server.on('request', async (req, res) => {
}
break;

case '/event':
inspector.instruments.events.push({
attributes: {
method: req.method,
path: req.url,
},
name: 'custom_event',
});
res.end('ok');
break;

case '/fetch':
const resp = await fetch('https://httpbin.org/anything', {
/*
Expand Down
4 changes: 4 additions & 0 deletions lib/inspector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import os from 'node:os';
import proc from 'node:process';
import { Session } from './session.js';
import { ErrorsInstrument } from './instruments/errors.js';
import { EventsInstrument } from './instruments/events.js';
import { LogsInstrument } from './instruments/logs.js';
import { MetricsInstrument } from './instruments/metrics.js';
import { NetworkInstrument } from './instruments/network.js';
Expand All @@ -17,6 +18,7 @@ export class Inspector {

instruments: {
errors: ErrorsInstrument;
events: EventsInstrument;
logs: LogsInstrument;
metrics: MetricsInstrument;
network: NetworkInstrument;
Expand Down Expand Up @@ -56,11 +58,13 @@ export class Inspector {
this.store = store;
this.instruments = {
errors: new ErrorsInstrument(store, instruments.errors),
events: new EventsInstrument(store, instruments.events),
logs: new LogsInstrument(store, instruments.logs),
metrics: new MetricsInstrument(store, instruments.metrics),
network: new NetworkInstrument(store, instruments.network),
traces: new TracesInstrument(store, instruments.traces),
};
this.activate();
}

activate() {
Expand Down

0 comments on commit 9098087

Please sign in to comment.