@futurewindai/wotchi 0.1.0-beta.1 → 0.1.0-beta.5
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 +182 -56
- package/SECURITY.md +2 -2
- package/dist/cjs/core/client.js +380 -21
- package/dist/cjs/core/config.js +177 -18
- package/dist/cjs/core/diagnostics.js +12 -1
- package/dist/cjs/core/group-store.js +15 -1
- package/dist/cjs/core/incident-builder.js +18 -0
- package/dist/cjs/core/incident-policy.js +2 -7
- package/dist/cjs/core/limits.js +13 -0
- package/dist/cjs/core/normalize.js +10 -5
- package/dist/cjs/core/notification-queue.js +20 -3
- package/dist/cjs/core/redact.js +83 -8
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/integrations/express/error-handler.js +4 -1
- package/dist/cjs/integrations/express/index.js +4 -1
- package/dist/cjs/integrations/express/state.js +30 -0
- package/dist/cjs/integrations/express/status-observer.js +86 -0
- package/dist/cjs/integrations/nest/exception-filter.js +9 -1
- package/dist/cjs/integrations/nest/index.js +3 -1
- package/dist/cjs/integrations/nest/register.js +9 -0
- package/dist/cjs/integrations/request-context.js +83 -1
- package/dist/cjs/notifiers/alert-payload.js +20 -0
- package/dist/cjs/notifiers/console.js +100 -10
- package/dist/cjs/notifiers/telegram-format.js +75 -5
- package/dist/cjs/notifiers/webhook-http.js +394 -0
- package/dist/cjs/notifiers/webhook.js +28 -0
- package/dist/esm/core/client.js +380 -21
- package/dist/esm/core/config.js +177 -18
- package/dist/esm/core/diagnostics.js +12 -1
- package/dist/esm/core/group-store.js +15 -1
- package/dist/esm/core/incident-builder.js +18 -0
- package/dist/esm/core/incident-policy.js +2 -7
- package/dist/esm/core/limits.js +10 -0
- package/dist/esm/core/normalize.js +10 -5
- package/dist/esm/core/notification-queue.js +20 -3
- package/dist/esm/core/redact.js +83 -8
- package/dist/esm/index.js +2 -1
- package/dist/esm/integrations/express/error-handler.js +4 -1
- package/dist/esm/integrations/express/index.js +2 -1
- package/dist/esm/integrations/express/state.js +26 -0
- package/dist/esm/integrations/express/status-observer.js +83 -0
- package/dist/esm/integrations/nest/exception-filter.js +9 -1
- package/dist/esm/integrations/nest/index.js +2 -2
- package/dist/esm/integrations/nest/register.js +8 -0
- package/dist/esm/integrations/request-context.js +83 -1
- package/dist/esm/notifiers/alert-payload.js +16 -0
- package/dist/esm/notifiers/console.js +100 -10
- package/dist/esm/notifiers/telegram-format.js +75 -5
- package/dist/esm/notifiers/webhook-http.js +387 -0
- package/dist/esm/notifiers/webhook.js +24 -0
- package/dist/types/core/config.d.ts +7 -1
- package/dist/types/core/diagnostics.d.ts +5 -1
- package/dist/types/core/limits.d.ts +10 -0
- package/dist/types/core/notification-queue.d.ts +5 -1
- package/dist/types/core/types.d.ts +97 -1
- package/dist/types/index.d.ts +4 -2
- package/dist/types/integrations/express/index.d.ts +4 -2
- package/dist/types/integrations/express/state.d.ts +2 -0
- package/dist/types/integrations/express/status-observer.d.ts +11 -0
- package/dist/types/integrations/nest/index.d.ts +4 -3
- package/dist/types/integrations/nest/register.d.ts +3 -0
- package/dist/types/integrations/request-context.d.ts +3 -0
- package/dist/types/notifiers/alert-payload.d.ts +5 -0
- package/dist/types/notifiers/console.d.ts +1 -1
- package/dist/types/notifiers/webhook-http.d.ts +37 -0
- package/dist/types/notifiers/webhook.d.ts +4 -0
- package/dist/types-cjs/core/client.d.cts +2 -0
- package/dist/types-cjs/core/config.d.cts +35 -0
- package/dist/types-cjs/core/diagnostics.d.cts +11 -0
- package/dist/types-cjs/core/errors.d.cts +3 -0
- package/dist/types-cjs/core/fingerprint.d.cts +3 -0
- package/dist/types-cjs/core/group-store.d.cts +15 -0
- package/dist/types-cjs/core/incident-builder.d.cts +3 -0
- package/dist/types-cjs/core/incident-policy.d.cts +15 -0
- package/dist/types-cjs/core/limits.d.cts +10 -0
- package/dist/types-cjs/core/normalize.d.cts +17 -0
- package/dist/types-cjs/core/notification-queue.d.cts +20 -0
- package/dist/types-cjs/core/process-monitor.d.cts +5 -0
- package/dist/types-cjs/core/redact.d.cts +11 -0
- package/dist/types-cjs/core/rolling-window.d.cts +12 -0
- package/dist/types-cjs/core/stack-frame.d.cts +2 -0
- package/dist/types-cjs/core/types.d.cts +205 -0
- package/dist/types-cjs/index.d.cts +11 -0
- package/dist/types-cjs/integrations/express/error-handler.d.cts +4 -0
- package/dist/types-cjs/integrations/express/index.d.cts +9 -0
- package/dist/types-cjs/integrations/express/request-context.d.cts +5 -0
- package/dist/types-cjs/integrations/express/state.d.cts +2 -0
- package/dist/types-cjs/integrations/express/status-observer.d.cts +11 -0
- package/dist/types-cjs/integrations/nest/exception-filter.d.cts +10 -0
- package/dist/types-cjs/integrations/nest/index.d.cts +5 -0
- package/dist/types-cjs/integrations/nest/register.d.cts +13 -0
- package/dist/types-cjs/integrations/nest/request-context.d.cts +5 -0
- package/dist/types-cjs/integrations/request-context.d.cts +16 -0
- package/dist/types-cjs/notifiers/alert-payload.d.cts +5 -0
- package/dist/types-cjs/notifiers/console.d.cts +3 -0
- package/dist/types-cjs/notifiers/telegram-format.d.cts +2 -0
- package/dist/types-cjs/notifiers/telegram-http.d.cts +21 -0
- package/dist/types-cjs/notifiers/telegram.d.cts +4 -0
- package/dist/types-cjs/notifiers/webhook-http.d.cts +37 -0
- package/dist/types-cjs/notifiers/webhook.d.cts +4 -0
- package/package.json +28 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { consoleNotifier, createWotchi, telegramNotifier } from "../../index.js";
|
|
2
|
-
export { registerWotchiNest } from "./register.js";
|
|
3
|
-
export type { ConsoleNotifierOptions, IncidentAlert, IncidentGroup, IncidentSeverity, SafeErrorEvent, TelegramNotifierOptions, WotchiClient, WotchiConfig, WotchiDiagnostics, WotchiEventInput, WotchiNotifier, WotchiRequestContext, } from "../../index.js";
|
|
1
|
+
export { consoleNotifier, createWotchi, telegramNotifier, webhookNotifier } from "../../index.js";
|
|
2
|
+
export { registerWotchiNest, registerWotchiNestStatusObserver } from "./register.js";
|
|
3
|
+
export type { ConsoleNotifierOptions, IncidentAlert, IncidentGroup, IncidentSeverity, SafeErrorEvent, TelegramNotifierOptions, WebhookNotifierOptions, WotchiBeforeSend, WotchiCaptureOptions, WotchiClient, WotchiConfig, WotchiDiagnostics, WotchiEventFilter, WotchiEventInput, WotchiFingerprintCallback, WotchiFingerprintOverride, WotchiIncidentRule, WotchiLinkTemplates, WotchiLinks, WotchiNotifier, WotchiRequestContext, WotchiTags, WotchiTestAlertResult, WotchiTestAlertStatus, WotchiTraceContext, } from "../../index.js";
|
|
4
4
|
export type { NestWotchiApplication, NestWotchiOptions } from "./register.js";
|
|
5
|
+
export type { WotchiStatusClass, WotchiStatusObserverOptions } from "../express/status-observer.js";
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { HttpAdapterHost } from "@nestjs/core";
|
|
2
2
|
import type { WotchiClient } from "../../core/types.js";
|
|
3
3
|
import type { NestWotchiOptions } from "./request-context.js";
|
|
4
|
+
import type { WotchiStatusObserverOptions } from "../express/status-observer.js";
|
|
4
5
|
export type { NestWotchiOptions } from "./request-context.js";
|
|
5
6
|
export interface NestWotchiApplication {
|
|
6
7
|
get(token: typeof HttpAdapterHost): InstanceType<typeof HttpAdapterHost>;
|
|
7
8
|
getHttpAdapter?: () => unknown;
|
|
9
|
+
use?: (...middleware: unknown[]) => unknown;
|
|
8
10
|
useGlobalFilters(...filters: unknown[]): unknown;
|
|
9
11
|
}
|
|
10
12
|
export declare function registerWotchiNest(app: unknown, client: WotchiClient, options?: NestWotchiOptions): void;
|
|
13
|
+
export declare function registerWotchiNestStatusObserver(app: unknown, client: WotchiClient, options?: WotchiStatusObserverOptions): void;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { WotchiRequestContext } from "../core/types.js";
|
|
2
2
|
export interface RequestContextOptions {
|
|
3
3
|
requestIdProperty?: string;
|
|
4
|
+
correlationIdProperty?: string;
|
|
5
|
+
traceContextProperty?: string;
|
|
4
6
|
}
|
|
5
7
|
export declare function normalizeRoutePath(value: unknown): string | undefined;
|
|
6
8
|
export interface RequestContextInput {
|
|
@@ -8,6 +10,7 @@ export interface RequestContextInput {
|
|
|
8
10
|
method?: unknown;
|
|
9
11
|
route?: unknown;
|
|
10
12
|
statusCode?: unknown;
|
|
13
|
+
trace?: unknown;
|
|
11
14
|
options?: RequestContextOptions;
|
|
12
15
|
}
|
|
13
16
|
export declare function buildRequestContext(input: RequestContextInput): WotchiRequestContext | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SafeNormalizedValue } from "../core/normalize.js";
|
|
2
|
+
import type { IncidentAlert } from "../core/types.js";
|
|
3
|
+
export type BoundedAlertPayload = Record<string, SafeNormalizedValue>;
|
|
4
|
+
export declare function toBoundedPayload(value: unknown): BoundedAlertPayload;
|
|
5
|
+
export declare function toBoundedAlertPayload(alert: IncidentAlert): BoundedAlertPayload;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ConsoleNotifierOptions, IncidentAlert, WotchiNotifier } from "../core/types.js";
|
|
2
|
-
export declare function formatConsoleAlert(alert: IncidentAlert): string;
|
|
2
|
+
export declare function formatConsoleAlert(alert: IncidentAlert, format?: "text" | "json"): string;
|
|
3
3
|
export declare function consoleNotifier(options?: ConsoleNotifierOptions): WotchiNotifier;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { IncidentAlert, WebhookNotifierOptions } from "../core/types.js";
|
|
2
|
+
export interface WebhookRequestOptions {
|
|
3
|
+
protocol: "http:" | "https:";
|
|
4
|
+
hostname: string;
|
|
5
|
+
port?: string;
|
|
6
|
+
method: "POST";
|
|
7
|
+
path: string;
|
|
8
|
+
headers: Record<string, string | number>;
|
|
9
|
+
allowPrivateDestinations?: boolean;
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
}
|
|
12
|
+
export interface WebhookResponse {
|
|
13
|
+
statusCode: number;
|
|
14
|
+
headers: Record<string, string | string[] | undefined>;
|
|
15
|
+
body: string;
|
|
16
|
+
}
|
|
17
|
+
export type WebhookRequestFunction = (options: WebhookRequestOptions, body: string, timeoutMs: number) => Promise<WebhookResponse>;
|
|
18
|
+
export interface WebhookSendOptions {
|
|
19
|
+
url: string;
|
|
20
|
+
alert: IncidentAlert;
|
|
21
|
+
headers?: Record<string, string>;
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
maxRetries?: number;
|
|
24
|
+
allowHttpLoopback?: boolean;
|
|
25
|
+
allowPrivateDestinations?: boolean;
|
|
26
|
+
payloadBuilder?: (alert: Readonly<IncidentAlert>) => unknown;
|
|
27
|
+
}
|
|
28
|
+
export declare function normalizeWebhookOptions(options: WebhookNotifierOptions): {
|
|
29
|
+
url: URL;
|
|
30
|
+
headers?: Record<string, string>;
|
|
31
|
+
timeoutMs: number;
|
|
32
|
+
maxRetries: number;
|
|
33
|
+
allowHttpLoopback: boolean;
|
|
34
|
+
allowPrivateDestinations: boolean;
|
|
35
|
+
payloadBuilder?: WebhookNotifierOptions["payloadBuilder"];
|
|
36
|
+
};
|
|
37
|
+
export declare function sendWebhookAlert(options: WebhookSendOptions, request?: WebhookRequestFunction): Promise<void>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WebhookNotifierOptions, WotchiNotifier } from "../core/types.js";
|
|
2
|
+
import { type WebhookRequestFunction } from "./webhook-http.js";
|
|
3
|
+
export declare function createWebhookNotifier(options: WebhookNotifierOptions, request?: WebhookRequestFunction): WotchiNotifier;
|
|
4
|
+
export declare function webhookNotifier(options: WebhookNotifierOptions): WotchiNotifier;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { WotchiConfig, WotchiIncidentRule, WotchiLinkTemplates, WotchiNotifier } from "./types.js";
|
|
2
|
+
import { WotchiConfigurationError } from "./errors.js";
|
|
3
|
+
export { WotchiConfigurationError };
|
|
4
|
+
export interface NormalizedWotchiConfig {
|
|
5
|
+
readonly service: string;
|
|
6
|
+
readonly environment: string;
|
|
7
|
+
readonly instance?: string;
|
|
8
|
+
readonly release?: string;
|
|
9
|
+
readonly enabled: boolean;
|
|
10
|
+
readonly filter?: WotchiConfig["filter"];
|
|
11
|
+
readonly fingerprint?: WotchiConfig["fingerprint"];
|
|
12
|
+
readonly beforeSend?: WotchiConfig["beforeSend"];
|
|
13
|
+
readonly links?: Readonly<WotchiLinkTemplates>;
|
|
14
|
+
readonly rules: readonly WotchiIncidentRule[];
|
|
15
|
+
readonly grouping: {
|
|
16
|
+
readonly windowMs: number;
|
|
17
|
+
readonly alertThreshold: number;
|
|
18
|
+
readonly cooldownMs: number;
|
|
19
|
+
readonly maxGroups: number;
|
|
20
|
+
readonly maxEventsPerWindow: number;
|
|
21
|
+
};
|
|
22
|
+
readonly queue: {
|
|
23
|
+
readonly maxPendingAlerts: number;
|
|
24
|
+
readonly concurrency: 1;
|
|
25
|
+
};
|
|
26
|
+
readonly privacy: {
|
|
27
|
+
readonly redactKeys: readonly string[];
|
|
28
|
+
readonly maxDepth: number;
|
|
29
|
+
readonly maxKeys: number;
|
|
30
|
+
readonly maxStringLength: number;
|
|
31
|
+
readonly maxStackLength: number;
|
|
32
|
+
};
|
|
33
|
+
readonly notifiers: readonly WotchiNotifier[];
|
|
34
|
+
}
|
|
35
|
+
export declare function validateConfig(config: WotchiConfig): Readonly<NormalizedWotchiConfig>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WotchiDiagnostics } from "./types.js";
|
|
2
|
+
export interface DiagnosticsState {
|
|
3
|
+
capturedEvents: number;
|
|
4
|
+
captureFailures: number;
|
|
5
|
+
fingerprintCallbackFailures: number;
|
|
6
|
+
filterFailures: number;
|
|
7
|
+
beforeSendFailures: number;
|
|
8
|
+
eventsSuppressed: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function createDiagnosticsState(): DiagnosticsState;
|
|
11
|
+
export declare function snapshotDiagnostics(state: DiagnosticsState, values: Omit<WotchiDiagnostics, "capturedEvents" | "captureFailures" | "fingerprintCallbackFailures" | "filterFailures" | "beforeSendFailures" | "eventsSuppressed">): Readonly<WotchiDiagnostics>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IncidentGroup, IncidentSeverity, SafeErrorEvent } from "./types.js";
|
|
2
|
+
export interface GroupStoreOptions {
|
|
3
|
+
maxGroups: number;
|
|
4
|
+
maxEventsPerWindow: number;
|
|
5
|
+
windowMs: number;
|
|
6
|
+
now?: () => number;
|
|
7
|
+
}
|
|
8
|
+
export interface GroupStore {
|
|
9
|
+
record(fingerprint: string, event: SafeErrorEvent, severity?: IncidentSeverity): IncidentGroup;
|
|
10
|
+
get(fingerprint: string): IncidentGroup | undefined;
|
|
11
|
+
markAlerted(fingerprint: string, timestamp?: number): IncidentGroup | undefined;
|
|
12
|
+
size(): number;
|
|
13
|
+
groupsEvicted(): number;
|
|
14
|
+
}
|
|
15
|
+
export declare function createGroupStore(options: GroupStoreOptions): GroupStore;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IncidentGroup, IncidentSeverity } from "./types.js";
|
|
2
|
+
export type IncidentEventKind = "error" | "manual" | "process-monitor";
|
|
3
|
+
export interface IncidentPolicyInput {
|
|
4
|
+
group: IncidentGroup;
|
|
5
|
+
now: number;
|
|
6
|
+
alertThreshold: number;
|
|
7
|
+
cooldownMs: number;
|
|
8
|
+
eventKind?: IncidentEventKind;
|
|
9
|
+
manualSeverity?: IncidentSeverity;
|
|
10
|
+
}
|
|
11
|
+
export interface IncidentPolicyDecision {
|
|
12
|
+
shouldAlert: boolean;
|
|
13
|
+
severity: IncidentSeverity;
|
|
14
|
+
}
|
|
15
|
+
export declare function evaluateIncidentPolicy(input: IncidentPolicyInput): IncidentPolicyDecision;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const MAX_GROUPS = 10000;
|
|
2
|
+
export declare const MAX_EVENTS_PER_WINDOW = 10000;
|
|
3
|
+
export declare const MAX_PENDING_ALERTS = 10000;
|
|
4
|
+
export declare const MAX_WINDOW_MS: number;
|
|
5
|
+
export declare const MAX_ALERT_THRESHOLD = 1000000;
|
|
6
|
+
export declare const MAX_COOLDOWN_MS: number;
|
|
7
|
+
export declare const MAX_NORMALIZATION_DEPTH = 20;
|
|
8
|
+
export declare const MAX_NORMALIZATION_KEYS = 10000;
|
|
9
|
+
export declare const MAX_NORMALIZATION_STRING_LENGTH = 32768;
|
|
10
|
+
export declare const MAX_NORMALIZATION_STACK_LENGTH = 32768;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface NormalizationLimits {
|
|
2
|
+
maxDepth: number;
|
|
3
|
+
maxKeys: number;
|
|
4
|
+
maxStringLength: number;
|
|
5
|
+
maxStackLength: number;
|
|
6
|
+
}
|
|
7
|
+
export type SafeNormalizedValue = null | boolean | number | string | SafeNormalizedValue[] | {
|
|
8
|
+
[key: string]: SafeNormalizedValue;
|
|
9
|
+
};
|
|
10
|
+
export interface NormalizedError {
|
|
11
|
+
name: string;
|
|
12
|
+
message: string;
|
|
13
|
+
stack?: string;
|
|
14
|
+
code?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function normalizeUnknown(value: unknown, limits?: Partial<NormalizationLimits>): SafeNormalizedValue;
|
|
17
|
+
export declare function normalizeError(error: unknown, limits?: Partial<NormalizationLimits>): NormalizedError;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IncidentAlert, WotchiNotifier } from "./types.js";
|
|
2
|
+
export interface NotificationQueueOptions {
|
|
3
|
+
maxPendingAlerts: number;
|
|
4
|
+
concurrency: 1;
|
|
5
|
+
onNotifierError?: (error: unknown, notifier: WotchiNotifier) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface NotificationJobResult {
|
|
8
|
+
notifierFailures: number;
|
|
9
|
+
sent: number;
|
|
10
|
+
}
|
|
11
|
+
export interface NotificationQueue {
|
|
12
|
+
enqueue(alert: IncidentAlert, notifiers: readonly WotchiNotifier[], onComplete?: (result: NotificationJobResult) => void): boolean;
|
|
13
|
+
flush(timeoutMs?: number): Promise<void>;
|
|
14
|
+
pending(): number;
|
|
15
|
+
alertsQueued(): number;
|
|
16
|
+
alertsDropped(): number;
|
|
17
|
+
alertsSent(): number;
|
|
18
|
+
notifierFailures(): number;
|
|
19
|
+
}
|
|
20
|
+
export declare function createNotificationQueue(options: NotificationQueueOptions): NotificationQueue;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NormalizedError, SafeNormalizedValue } from "./normalize.js";
|
|
2
|
+
export declare const REDACTED = "[REDACTED]";
|
|
3
|
+
export interface RedactionOptions {
|
|
4
|
+
redactKeys?: readonly string[];
|
|
5
|
+
maxDepth?: number;
|
|
6
|
+
maxKeys?: number;
|
|
7
|
+
maxStringLength?: number;
|
|
8
|
+
maxStackLength?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function redactValue(value: unknown, options?: RedactionOptions): SafeNormalizedValue;
|
|
11
|
+
export declare function redactError(error: NormalizedError, options?: RedactionOptions): NormalizedError;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface RollingWindowOptions {
|
|
2
|
+
maxEvents: number;
|
|
3
|
+
windowMs: number;
|
|
4
|
+
now?: () => number;
|
|
5
|
+
}
|
|
6
|
+
export interface RollingWindow {
|
|
7
|
+
add(timestamp?: number): void;
|
|
8
|
+
count(timestamp?: number): number;
|
|
9
|
+
size(timestamp?: number): number;
|
|
10
|
+
timestamps(timestamp?: number): readonly number[];
|
|
11
|
+
}
|
|
12
|
+
export declare function createRollingWindow(options: RollingWindowOptions): RollingWindow;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
export type IncidentSeverity = "low" | "medium" | "high" | "critical";
|
|
2
|
+
export type WotchiEventKind = "error" | "manual" | "process-monitor";
|
|
3
|
+
export interface WotchiTraceContext {
|
|
4
|
+
traceId?: string;
|
|
5
|
+
spanId?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface WotchiRequestContext extends Record<string, unknown> {
|
|
8
|
+
method?: string;
|
|
9
|
+
route?: string;
|
|
10
|
+
statusCode?: number;
|
|
11
|
+
requestId?: string;
|
|
12
|
+
correlationId?: string;
|
|
13
|
+
trace?: WotchiTraceContext;
|
|
14
|
+
}
|
|
15
|
+
export type WotchiTags = Readonly<Record<string, string>>;
|
|
16
|
+
export interface WotchiLinkTemplates {
|
|
17
|
+
log?: string;
|
|
18
|
+
trace?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface WotchiLinks {
|
|
21
|
+
log?: string;
|
|
22
|
+
trace?: string;
|
|
23
|
+
}
|
|
24
|
+
export type WotchiFingerprintCallback = (event: Readonly<SafeErrorEvent>) => string | undefined;
|
|
25
|
+
export type WotchiFingerprintOverride = string | WotchiFingerprintCallback;
|
|
26
|
+
export type WotchiEventFilter = (event: Readonly<SafeErrorEvent>) => boolean;
|
|
27
|
+
export type WotchiBeforeSend = (alert: Readonly<IncidentAlert>) => IncidentAlert | null | undefined;
|
|
28
|
+
export interface WotchiCaptureOptions {
|
|
29
|
+
fingerprint?: WotchiFingerprintOverride;
|
|
30
|
+
severity?: IncidentSeverity;
|
|
31
|
+
alertThreshold?: number;
|
|
32
|
+
request?: WotchiRequestContext;
|
|
33
|
+
trace?: WotchiTraceContext;
|
|
34
|
+
correlationId?: string;
|
|
35
|
+
operation?: string;
|
|
36
|
+
job?: string;
|
|
37
|
+
tags?: Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
export interface WotchiEventInput {
|
|
40
|
+
level: "error";
|
|
41
|
+
kind?: WotchiEventKind;
|
|
42
|
+
message: string;
|
|
43
|
+
error?: unknown;
|
|
44
|
+
alertThreshold?: number;
|
|
45
|
+
severity?: IncidentSeverity;
|
|
46
|
+
fingerprint?: WotchiFingerprintOverride;
|
|
47
|
+
metadata?: Record<string, unknown>;
|
|
48
|
+
context?: Record<string, unknown>;
|
|
49
|
+
request?: WotchiRequestContext;
|
|
50
|
+
trace?: WotchiTraceContext;
|
|
51
|
+
correlationId?: string;
|
|
52
|
+
operation?: string;
|
|
53
|
+
job?: string;
|
|
54
|
+
tags?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
export interface SafeErrorEvent {
|
|
57
|
+
id: string;
|
|
58
|
+
timestamp: string;
|
|
59
|
+
service: string;
|
|
60
|
+
environment: string;
|
|
61
|
+
instance?: string;
|
|
62
|
+
release?: string;
|
|
63
|
+
correlationId?: string;
|
|
64
|
+
operation?: string;
|
|
65
|
+
job?: string;
|
|
66
|
+
tags?: WotchiTags;
|
|
67
|
+
error: {
|
|
68
|
+
name: string;
|
|
69
|
+
message: string;
|
|
70
|
+
stack?: string;
|
|
71
|
+
code?: string;
|
|
72
|
+
};
|
|
73
|
+
request?: WotchiRequestContext;
|
|
74
|
+
trace?: WotchiTraceContext;
|
|
75
|
+
context?: Record<string, unknown>;
|
|
76
|
+
}
|
|
77
|
+
export interface IncidentGroup {
|
|
78
|
+
fingerprint: string;
|
|
79
|
+
firstSeenAt: string;
|
|
80
|
+
lastSeenAt: string;
|
|
81
|
+
totalCount: number;
|
|
82
|
+
windowCount: number;
|
|
83
|
+
sample: SafeErrorEvent;
|
|
84
|
+
lastAlertedAt?: string;
|
|
85
|
+
severity: IncidentSeverity;
|
|
86
|
+
}
|
|
87
|
+
export interface IncidentAlert {
|
|
88
|
+
id: string;
|
|
89
|
+
fingerprint: string;
|
|
90
|
+
title: string;
|
|
91
|
+
severity: IncidentSeverity;
|
|
92
|
+
summary: string;
|
|
93
|
+
suggestedActions: string[];
|
|
94
|
+
firstSeenAt: string;
|
|
95
|
+
lastSeenAt: string;
|
|
96
|
+
occurrences: number;
|
|
97
|
+
service: string;
|
|
98
|
+
environment: string;
|
|
99
|
+
instance?: string;
|
|
100
|
+
release?: string;
|
|
101
|
+
correlationId?: string;
|
|
102
|
+
operation?: string;
|
|
103
|
+
job?: string;
|
|
104
|
+
tags?: WotchiTags;
|
|
105
|
+
error?: SafeErrorEvent["error"] & {
|
|
106
|
+
applicationFrame?: string;
|
|
107
|
+
};
|
|
108
|
+
request?: WotchiRequestContext;
|
|
109
|
+
trace?: WotchiTraceContext;
|
|
110
|
+
context?: Record<string, unknown>;
|
|
111
|
+
links?: WotchiLinks;
|
|
112
|
+
}
|
|
113
|
+
export interface WotchiNotifier {
|
|
114
|
+
readonly name: string;
|
|
115
|
+
send(alert: IncidentAlert): Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
export interface ConsoleNotifierOptions {
|
|
118
|
+
write?: (line: string) => void;
|
|
119
|
+
format?: "text" | "json";
|
|
120
|
+
}
|
|
121
|
+
export interface TelegramNotifierOptions {
|
|
122
|
+
botToken: string;
|
|
123
|
+
chatId: string;
|
|
124
|
+
timeoutMs?: number;
|
|
125
|
+
}
|
|
126
|
+
export interface WebhookNotifierOptions {
|
|
127
|
+
url: string;
|
|
128
|
+
headers?: Record<string, string>;
|
|
129
|
+
timeoutMs?: number;
|
|
130
|
+
maxRetries?: number;
|
|
131
|
+
allowHttpLoopback?: boolean;
|
|
132
|
+
allowPrivateDestinations?: boolean;
|
|
133
|
+
payloadBuilder?: (alert: Readonly<IncidentAlert>) => unknown;
|
|
134
|
+
}
|
|
135
|
+
export interface WotchiIncidentRule {
|
|
136
|
+
environment?: string;
|
|
137
|
+
route?: string;
|
|
138
|
+
ignore?: boolean;
|
|
139
|
+
alertThreshold?: number;
|
|
140
|
+
severity?: IncidentSeverity;
|
|
141
|
+
}
|
|
142
|
+
export interface WotchiConfig {
|
|
143
|
+
service: string;
|
|
144
|
+
environment: string;
|
|
145
|
+
instance?: string;
|
|
146
|
+
release?: string;
|
|
147
|
+
enabled?: boolean;
|
|
148
|
+
filter?: WotchiEventFilter;
|
|
149
|
+
fingerprint?: WotchiFingerprintCallback;
|
|
150
|
+
beforeSend?: WotchiBeforeSend;
|
|
151
|
+
links?: WotchiLinkTemplates;
|
|
152
|
+
rules?: readonly WotchiIncidentRule[];
|
|
153
|
+
grouping?: {
|
|
154
|
+
windowMs?: number;
|
|
155
|
+
alertThreshold?: number;
|
|
156
|
+
cooldownMs?: number;
|
|
157
|
+
maxGroups?: number;
|
|
158
|
+
maxEventsPerWindow?: number;
|
|
159
|
+
};
|
|
160
|
+
queue?: {
|
|
161
|
+
maxPendingAlerts?: number;
|
|
162
|
+
concurrency?: 1;
|
|
163
|
+
};
|
|
164
|
+
privacy?: {
|
|
165
|
+
redactKeys?: string[];
|
|
166
|
+
maxDepth?: number;
|
|
167
|
+
maxKeys?: number;
|
|
168
|
+
maxStringLength?: number;
|
|
169
|
+
maxStackLength?: number;
|
|
170
|
+
};
|
|
171
|
+
notifiers: WotchiNotifier[];
|
|
172
|
+
}
|
|
173
|
+
export interface WotchiDiagnostics {
|
|
174
|
+
capturedEvents: number;
|
|
175
|
+
captureFailures: number;
|
|
176
|
+
groupsEvicted: number;
|
|
177
|
+
alertsQueued: number;
|
|
178
|
+
alertsDropped: number;
|
|
179
|
+
alertsSent: number;
|
|
180
|
+
notifierFailures: number;
|
|
181
|
+
fingerprintCallbackFailures: number;
|
|
182
|
+
filterFailures: number;
|
|
183
|
+
beforeSendFailures: number;
|
|
184
|
+
eventsSuppressed: number;
|
|
185
|
+
activeGroups: number;
|
|
186
|
+
pendingAlerts: number;
|
|
187
|
+
}
|
|
188
|
+
export type WotchiTestAlertStatus = "sent" | "queue-full" | "timeout" | "notifier-failed";
|
|
189
|
+
export interface WotchiTestAlertResult {
|
|
190
|
+
status: WotchiTestAlertStatus;
|
|
191
|
+
configurationAccepted: true;
|
|
192
|
+
queued: boolean;
|
|
193
|
+
flushed: boolean;
|
|
194
|
+
delivered: boolean;
|
|
195
|
+
notifierFailures: number;
|
|
196
|
+
diagnostics: Readonly<WotchiDiagnostics>;
|
|
197
|
+
error?: string;
|
|
198
|
+
}
|
|
199
|
+
export interface WotchiClient {
|
|
200
|
+
captureException(error: unknown, context?: Record<string, unknown>, options?: WotchiCaptureOptions): void;
|
|
201
|
+
captureEvent(event: WotchiEventInput): void;
|
|
202
|
+
testAlert(): Promise<WotchiTestAlertResult>;
|
|
203
|
+
flush(timeoutMs?: number): Promise<void>;
|
|
204
|
+
getDiagnostics(): Readonly<WotchiDiagnostics>;
|
|
205
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createWotchi } from "./core/client.js";
|
|
2
|
+
import { registerWotchiProcessMonitor } from "./core/process-monitor.js";
|
|
3
|
+
import { consoleNotifier } from "./notifiers/console.js";
|
|
4
|
+
import { telegramNotifier } from "./notifiers/telegram.js";
|
|
5
|
+
import { webhookNotifier } from "./notifiers/webhook.js";
|
|
6
|
+
export { WotchiConfigurationError } from "./core/errors.js";
|
|
7
|
+
export type { ProcessMonitorHandle } from "./core/process-monitor.js";
|
|
8
|
+
export type { NormalizedWotchiConfig } from "./core/config.js";
|
|
9
|
+
export type { ConsoleNotifierOptions, IncidentAlert, IncidentGroup, IncidentSeverity, SafeErrorEvent, TelegramNotifierOptions, WebhookNotifierOptions, WotchiBeforeSend, WotchiCaptureOptions, WotchiClient, WotchiConfig, WotchiDiagnostics, WotchiEventFilter, WotchiEventInput, WotchiEventKind, WotchiFingerprintOverride, WotchiFingerprintCallback, WotchiIncidentRule, WotchiLinkTemplates, WotchiLinks, WotchiNotifier, WotchiRequestContext, WotchiTags, WotchiTestAlertResult, WotchiTestAlertStatus, WotchiTraceContext, } from "./core/types.js";
|
|
10
|
+
export type { WebhookRequestFunction, WebhookRequestOptions, WebhookResponse, } from "./notifiers/webhook-http.js";
|
|
11
|
+
export { consoleNotifier, createWotchi, registerWotchiProcessMonitor, telegramNotifier, webhookNotifier, };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ErrorRequestHandler } from "express";
|
|
2
|
+
import type { WotchiClient } from "../../core/types.js";
|
|
3
|
+
import { type ExpressWotchiOptions } from "./request-context.js";
|
|
4
|
+
export declare function createExpressErrorHandler(client: WotchiClient, options?: ExpressWotchiOptions): ErrorRequestHandler;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WotchiClient } from "../../core/types.js";
|
|
2
|
+
import { createExpressErrorHandler } from "./error-handler.js";
|
|
3
|
+
import type { ExpressWotchiOptions } from "./request-context.js";
|
|
4
|
+
export { consoleNotifier, createWotchi, telegramNotifier, webhookNotifier } from "../../index.js";
|
|
5
|
+
export type { ConsoleNotifierOptions, IncidentAlert, IncidentGroup, IncidentSeverity, SafeErrorEvent, TelegramNotifierOptions, WebhookNotifierOptions, WotchiBeforeSend, WotchiCaptureOptions, WotchiClient, WotchiConfig, WotchiDiagnostics, WotchiEventFilter, WotchiEventInput, WotchiFingerprintCallback, WotchiFingerprintOverride, WotchiIncidentRule, WotchiLinkTemplates, WotchiLinks, WotchiNotifier, WotchiRequestContext, WotchiTags, WotchiTestAlertResult, WotchiTestAlertStatus, WotchiTraceContext, } from "../../index.js";
|
|
6
|
+
export type { ExpressWotchiOptions } from "./request-context.js";
|
|
7
|
+
export type { WotchiStatusClass, WotchiStatusObserverOptions } from "./status-observer.js";
|
|
8
|
+
export { wotchiStatusObserver } from "./status-observer.js";
|
|
9
|
+
export declare function wotchiErrorHandler(client: WotchiClient, options?: ExpressWotchiOptions): ReturnType<typeof createExpressErrorHandler>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
import { type RequestContextOptions } from "../request-context.js";
|
|
3
|
+
import type { WotchiRequestContext } from "../../core/types.js";
|
|
4
|
+
export type ExpressWotchiOptions = RequestContextOptions;
|
|
5
|
+
export declare function getExpressRequestContext(request: Request, response: Response, options?: ExpressWotchiOptions): WotchiRequestContext | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RequestHandler } from "express";
|
|
2
|
+
import type { WotchiClient } from "../../core/types.js";
|
|
3
|
+
import type { RequestContextOptions } from "../request-context.js";
|
|
4
|
+
export type WotchiStatusClass = "4xx" | "5xx";
|
|
5
|
+
export interface WotchiStatusObserverOptions extends RequestContextOptions {
|
|
6
|
+
statusCodes?: readonly number[];
|
|
7
|
+
statusClasses?: readonly WotchiStatusClass[];
|
|
8
|
+
ignoreStatusCodes?: readonly number[];
|
|
9
|
+
alertThreshold?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function wotchiStatusObserver(client: WotchiClient, options?: WotchiStatusObserverOptions): RequestHandler;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ArgumentsHost, type HttpServer } from "@nestjs/common";
|
|
2
|
+
import { BaseExceptionFilter } from "@nestjs/core";
|
|
3
|
+
import type { WotchiClient } from "../../core/types.js";
|
|
4
|
+
import { type NestWotchiOptions } from "./request-context.js";
|
|
5
|
+
export declare class WotchiNestExceptionFilter extends BaseExceptionFilter<unknown> {
|
|
6
|
+
private readonly client;
|
|
7
|
+
private readonly options?;
|
|
8
|
+
constructor(client: WotchiClient, applicationRef: HttpServer, options?: NestWotchiOptions | undefined);
|
|
9
|
+
catch(exception: unknown, host: ArgumentsHost): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { consoleNotifier, createWotchi, telegramNotifier, webhookNotifier } from "../../index.js";
|
|
2
|
+
export { registerWotchiNest, registerWotchiNestStatusObserver } from "./register.js";
|
|
3
|
+
export type { ConsoleNotifierOptions, IncidentAlert, IncidentGroup, IncidentSeverity, SafeErrorEvent, TelegramNotifierOptions, WebhookNotifierOptions, WotchiBeforeSend, WotchiCaptureOptions, WotchiClient, WotchiConfig, WotchiDiagnostics, WotchiEventFilter, WotchiEventInput, WotchiFingerprintCallback, WotchiFingerprintOverride, WotchiIncidentRule, WotchiLinkTemplates, WotchiLinks, WotchiNotifier, WotchiRequestContext, WotchiTags, WotchiTestAlertResult, WotchiTestAlertStatus, WotchiTraceContext, } from "../../index.js";
|
|
4
|
+
export type { NestWotchiApplication, NestWotchiOptions } from "./register.js";
|
|
5
|
+
export type { WotchiStatusClass, WotchiStatusObserverOptions } from "../express/status-observer.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HttpAdapterHost } from "@nestjs/core";
|
|
2
|
+
import type { WotchiClient } from "../../core/types.js";
|
|
3
|
+
import type { NestWotchiOptions } from "./request-context.js";
|
|
4
|
+
import type { WotchiStatusObserverOptions } from "../express/status-observer.js";
|
|
5
|
+
export type { NestWotchiOptions } from "./request-context.js";
|
|
6
|
+
export interface NestWotchiApplication {
|
|
7
|
+
get(token: typeof HttpAdapterHost): InstanceType<typeof HttpAdapterHost>;
|
|
8
|
+
getHttpAdapter?: () => unknown;
|
|
9
|
+
use?: (...middleware: unknown[]) => unknown;
|
|
10
|
+
useGlobalFilters(...filters: unknown[]): unknown;
|
|
11
|
+
}
|
|
12
|
+
export declare function registerWotchiNest(app: unknown, client: WotchiClient, options?: NestWotchiOptions): void;
|
|
13
|
+
export declare function registerWotchiNestStatusObserver(app: unknown, client: WotchiClient, options?: WotchiStatusObserverOptions): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ArgumentsHost } from "@nestjs/common";
|
|
2
|
+
import { type RequestContextOptions } from "../request-context.js";
|
|
3
|
+
import type { WotchiRequestContext } from "../../core/types.js";
|
|
4
|
+
export type NestWotchiOptions = RequestContextOptions;
|
|
5
|
+
export declare function getNestRequestContext(host: ArgumentsHost, exception: unknown, options?: NestWotchiOptions): WotchiRequestContext | undefined;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WotchiRequestContext } from "../core/types.js";
|
|
2
|
+
export interface RequestContextOptions {
|
|
3
|
+
requestIdProperty?: string;
|
|
4
|
+
correlationIdProperty?: string;
|
|
5
|
+
traceContextProperty?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function normalizeRoutePath(value: unknown): string | undefined;
|
|
8
|
+
export interface RequestContextInput {
|
|
9
|
+
request?: unknown;
|
|
10
|
+
method?: unknown;
|
|
11
|
+
route?: unknown;
|
|
12
|
+
statusCode?: unknown;
|
|
13
|
+
trace?: unknown;
|
|
14
|
+
options?: RequestContextOptions;
|
|
15
|
+
}
|
|
16
|
+
export declare function buildRequestContext(input: RequestContextInput): WotchiRequestContext | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SafeNormalizedValue } from "../core/normalize.js";
|
|
2
|
+
import type { IncidentAlert } from "../core/types.js";
|
|
3
|
+
export type BoundedAlertPayload = Record<string, SafeNormalizedValue>;
|
|
4
|
+
export declare function toBoundedPayload(value: unknown): BoundedAlertPayload;
|
|
5
|
+
export declare function toBoundedAlertPayload(alert: IncidentAlert): BoundedAlertPayload;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ConsoleNotifierOptions, IncidentAlert, WotchiNotifier } from "../core/types.js";
|
|
2
|
+
export declare function formatConsoleAlert(alert: IncidentAlert, format?: "text" | "json"): string;
|
|
3
|
+
export declare function consoleNotifier(options?: ConsoleNotifierOptions): WotchiNotifier;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RequestOptions } from "node:https";
|
|
2
|
+
export interface TelegramHttpRequestOptions extends RequestOptions {
|
|
3
|
+
protocol: "https:";
|
|
4
|
+
hostname: "api.telegram.org";
|
|
5
|
+
method: "POST";
|
|
6
|
+
path: string;
|
|
7
|
+
headers: Record<string, string | number>;
|
|
8
|
+
}
|
|
9
|
+
export interface TelegramHttpResponse {
|
|
10
|
+
statusCode: number;
|
|
11
|
+
headers: Record<string, string | string[] | undefined>;
|
|
12
|
+
body: string;
|
|
13
|
+
}
|
|
14
|
+
export type TelegramRequestFunction = (options: TelegramHttpRequestOptions, body: string, timeoutMs: number) => Promise<TelegramHttpResponse>;
|
|
15
|
+
export interface TelegramSendOptions {
|
|
16
|
+
botToken: string;
|
|
17
|
+
chatId: string;
|
|
18
|
+
text: string;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function sendTelegramMessage(options: TelegramSendOptions, request?: TelegramRequestFunction): Promise<void>;
|