@juice-js/observability 0.0.0-stage → 1.0.0-alpha.1
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 +31 -2
- package/fesm2022/juice-js-observability-alert.page-D2OL0zTT.mjs +405 -0
- package/fesm2022/juice-js-observability-alert.page-D2OL0zTT.mjs.map +1 -0
- package/fesm2022/juice-js-observability-alerts.page-BLJvD_op.mjs +208 -0
- package/fesm2022/juice-js-observability-alerts.page-BLJvD_op.mjs.map +1 -0
- package/fesm2022/juice-js-observability-logs.page-BWFLleyX.mjs +414 -0
- package/fesm2022/juice-js-observability-logs.page-BWFLleyX.mjs.map +1 -0
- package/fesm2022/juice-js-observability-metrics.page-D1caPbQq.mjs +268 -0
- package/fesm2022/juice-js-observability-metrics.page-D1caPbQq.mjs.map +1 -0
- package/fesm2022/juice-js-observability-overview.page-UBwHjlyq.mjs +213 -0
- package/fesm2022/juice-js-observability-overview.page-UBwHjlyq.mjs.map +1 -0
- package/fesm2022/juice-js-observability-resource.page-BZwLK_vU.mjs +275 -0
- package/fesm2022/juice-js-observability-resource.page-BZwLK_vU.mjs.map +1 -0
- package/fesm2022/juice-js-observability-resources.page-C0xWOb5I.mjs +210 -0
- package/fesm2022/juice-js-observability-resources.page-C0xWOb5I.mjs.map +1 -0
- package/fesm2022/juice-js-observability-rules.page-Db_U5rRu.mjs +176 -0
- package/fesm2022/juice-js-observability-rules.page-Db_U5rRu.mjs.map +1 -0
- package/fesm2022/juice-js-observability-service.page-B-SWJ9I5.mjs +727 -0
- package/fesm2022/juice-js-observability-service.page-B-SWJ9I5.mjs.map +1 -0
- package/fesm2022/juice-js-observability-services.page-BmWgFnC8.mjs +252 -0
- package/fesm2022/juice-js-observability-services.page-BmWgFnC8.mjs.map +1 -0
- package/fesm2022/juice-js-observability-telemetry-VA4_3nzr.mjs +1748 -0
- package/fesm2022/juice-js-observability-telemetry-VA4_3nzr.mjs.map +1 -0
- package/fesm2022/juice-js-observability-topology.page-DEUNp10U.mjs +458 -0
- package/fesm2022/juice-js-observability-topology.page-DEUNp10U.mjs.map +1 -0
- package/fesm2022/juice-js-observability-trace.page-gBhMG2eQ.mjs +530 -0
- package/fesm2022/juice-js-observability-trace.page-gBhMG2eQ.mjs.map +1 -0
- package/fesm2022/juice-js-observability-traces.page-BCQg4V4o.mjs +521 -0
- package/fesm2022/juice-js-observability-traces.page-BCQg4V4o.mjs.map +1 -0
- package/fesm2022/juice-js-observability.mjs +396 -0
- package/fesm2022/juice-js-observability.mjs.map +1 -0
- package/package.json +48 -4
- package/styles/_observability.scss +133 -0
- package/types/juice-js-observability.d.ts +387 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { EnvironmentProviders, InjectionToken, PipeTransform } from "@angular/core";
|
|
3
|
+
import { Observable } from "rxjs";
|
|
4
|
+
import { Params, Routes } from "@angular/router";
|
|
5
|
+
import { Menus } from "@juice-js/core";
|
|
6
|
+
/** How the host app mounts Juice Observability. */
|
|
7
|
+
export interface ObservabilityOptions {
|
|
8
|
+
/** The Juice API origin; empty when the API serves the app (same origin). */
|
|
9
|
+
apiBase: string;
|
|
10
|
+
/** Where the host mounts {@link OBSERVABILITY_ROUTES}: `/` for the whole app, or a path such as `/observability`. */
|
|
11
|
+
basePath: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const OBSERVABILITY_OPTIONS: InjectionToken<ObservabilityOptions>;
|
|
14
|
+
/** Configures the pages: where the API is and where the host mounted the routes. */
|
|
15
|
+
export declare function provideJuiceObservability(options?: Partial<ObservabilityOptions>): EnvironmentProviders;
|
|
16
|
+
/** `/observability/` → `/observability`; `` and `/` → `/`. */
|
|
17
|
+
export declare function normalizeBasePath(basePath: string): string;
|
|
18
|
+
/** Router links to the pages, under the host's mount path. */
|
|
19
|
+
export declare class ObservabilityLinks {
|
|
20
|
+
readonly base: string;
|
|
21
|
+
/** `to('services', id)` → `['/observability', 'services', id]`. */
|
|
22
|
+
to(...segments: unknown[]): unknown[];
|
|
23
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ObservabilityLinks, never>;
|
|
24
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
25
|
+
}
|
|
26
|
+
/** `['services', id] | jcLink`: the same as {@link ObservabilityLinks.to} in a template. */
|
|
27
|
+
export declare class LinkPipe implements PipeTransform {
|
|
28
|
+
private readonly links;
|
|
29
|
+
transform(segments: unknown[]): unknown[];
|
|
30
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LinkPipe, never>;
|
|
31
|
+
static ɵpipe: i0.ɵɵPipeDeclaration<LinkPipe, "jcLink", true>;
|
|
32
|
+
}
|
|
33
|
+
export interface Page<T> {
|
|
34
|
+
items: T[];
|
|
35
|
+
nextCursor: string | null;
|
|
36
|
+
}
|
|
37
|
+
export interface TelemetryPage<T> {
|
|
38
|
+
items: T[];
|
|
39
|
+
truncated: boolean;
|
|
40
|
+
nextCursor?: string | null;
|
|
41
|
+
}
|
|
42
|
+
export interface Tenant {
|
|
43
|
+
id: string;
|
|
44
|
+
key: string;
|
|
45
|
+
displayName: string;
|
|
46
|
+
}
|
|
47
|
+
export interface DeploymentEnvironment {
|
|
48
|
+
id: string;
|
|
49
|
+
key: string;
|
|
50
|
+
type: string;
|
|
51
|
+
firstSeen: string;
|
|
52
|
+
lastSeen: string;
|
|
53
|
+
}
|
|
54
|
+
export interface Application {
|
|
55
|
+
id: string;
|
|
56
|
+
key: string;
|
|
57
|
+
displayName: string;
|
|
58
|
+
services: number;
|
|
59
|
+
firstSeen: string;
|
|
60
|
+
lastSeen: string;
|
|
61
|
+
}
|
|
62
|
+
export interface ResourceSummary {
|
|
63
|
+
id: string;
|
|
64
|
+
type: string;
|
|
65
|
+
key: string;
|
|
66
|
+
displayName: string;
|
|
67
|
+
firstSeen: string;
|
|
68
|
+
lastSeen: string;
|
|
69
|
+
}
|
|
70
|
+
export type HealthState = 'Healthy' | 'Degraded' | 'Unhealthy' | 'Critical' | 'Offline' | 'Unknown';
|
|
71
|
+
export interface Health {
|
|
72
|
+
subjectType: string;
|
|
73
|
+
subjectId: string;
|
|
74
|
+
subjectName: string;
|
|
75
|
+
environment: string | null;
|
|
76
|
+
state: HealthState;
|
|
77
|
+
reasons: string[];
|
|
78
|
+
policyVersion: string;
|
|
79
|
+
evaluatedAt: string;
|
|
80
|
+
evidenceFrom: string;
|
|
81
|
+
evidenceTo: string;
|
|
82
|
+
lastEvidenceAt: string | null;
|
|
83
|
+
since: string;
|
|
84
|
+
stale: boolean;
|
|
85
|
+
}
|
|
86
|
+
export interface Instance {
|
|
87
|
+
id: string;
|
|
88
|
+
environment: string;
|
|
89
|
+
instanceKey: string;
|
|
90
|
+
keySource: string;
|
|
91
|
+
serviceVersion: string | null;
|
|
92
|
+
state: string;
|
|
93
|
+
hostResourceId: string | null;
|
|
94
|
+
firstSeen: string;
|
|
95
|
+
lastSeen: string;
|
|
96
|
+
health: HealthState | null;
|
|
97
|
+
}
|
|
98
|
+
export interface IntegrationLink {
|
|
99
|
+
integration: string;
|
|
100
|
+
title: string;
|
|
101
|
+
url: string;
|
|
102
|
+
}
|
|
103
|
+
export interface ResourceDetail {
|
|
104
|
+
id: string;
|
|
105
|
+
type: string;
|
|
106
|
+
key: string;
|
|
107
|
+
displayName: string;
|
|
108
|
+
firstSeen: string;
|
|
109
|
+
lastSeen: string;
|
|
110
|
+
namespace: string | null;
|
|
111
|
+
name: string | null;
|
|
112
|
+
applicationId: string | null;
|
|
113
|
+
attributes: Record<string, string>;
|
|
114
|
+
instances: Instance[];
|
|
115
|
+
instancesTruncated: boolean;
|
|
116
|
+
health: Health[];
|
|
117
|
+
links: IntegrationLink[];
|
|
118
|
+
}
|
|
119
|
+
export interface TopologyNode {
|
|
120
|
+
id: string;
|
|
121
|
+
type: string;
|
|
122
|
+
displayName: string;
|
|
123
|
+
health: HealthState | null;
|
|
124
|
+
}
|
|
125
|
+
export interface TopologyEdge {
|
|
126
|
+
id: string;
|
|
127
|
+
source: string;
|
|
128
|
+
target: string;
|
|
129
|
+
relation: string;
|
|
130
|
+
confidence: string;
|
|
131
|
+
evidenceSource: string;
|
|
132
|
+
spanCount: number;
|
|
133
|
+
firstSeen: string;
|
|
134
|
+
lastSeen: string;
|
|
135
|
+
}
|
|
136
|
+
export interface Topology {
|
|
137
|
+
environment: string | null;
|
|
138
|
+
nodes: TopologyNode[];
|
|
139
|
+
edges: TopologyEdge[];
|
|
140
|
+
truncated: boolean;
|
|
141
|
+
}
|
|
142
|
+
export interface Alert {
|
|
143
|
+
id: string;
|
|
144
|
+
rule: string;
|
|
145
|
+
subjectKey: string;
|
|
146
|
+
subjectType: string;
|
|
147
|
+
subjectId: string | null;
|
|
148
|
+
environment: string | null;
|
|
149
|
+
severity: string;
|
|
150
|
+
state: string;
|
|
151
|
+
breachStartedAt: string | null;
|
|
152
|
+
firedAt: string | null;
|
|
153
|
+
resolvedAt: string | null;
|
|
154
|
+
lastEvaluatedAt: string;
|
|
155
|
+
lastValue: number | null;
|
|
156
|
+
noData: boolean;
|
|
157
|
+
acknowledgedAt: string | null;
|
|
158
|
+
acknowledgedBy: string | null;
|
|
159
|
+
}
|
|
160
|
+
export interface AlertTransition {
|
|
161
|
+
from: string | null;
|
|
162
|
+
to: string;
|
|
163
|
+
at: string;
|
|
164
|
+
value: number | null;
|
|
165
|
+
reason: string;
|
|
166
|
+
}
|
|
167
|
+
export interface AlertDetail {
|
|
168
|
+
alert: Alert;
|
|
169
|
+
evidence: Record<string, string>;
|
|
170
|
+
acknowledgeComment: string | null;
|
|
171
|
+
history: AlertTransition[];
|
|
172
|
+
subjectHealth: Health[];
|
|
173
|
+
links: IntegrationLink[];
|
|
174
|
+
}
|
|
175
|
+
export interface Rule {
|
|
176
|
+
key: string;
|
|
177
|
+
name: string;
|
|
178
|
+
template: string;
|
|
179
|
+
severity: string;
|
|
180
|
+
enabled: boolean;
|
|
181
|
+
definition: Record<string, unknown>;
|
|
182
|
+
loadedAt: string;
|
|
183
|
+
}
|
|
184
|
+
export interface TraceSummary {
|
|
185
|
+
traceId: string;
|
|
186
|
+
startedAt: string;
|
|
187
|
+
durationMs: number;
|
|
188
|
+
rootService: string;
|
|
189
|
+
rootOperation: string;
|
|
190
|
+
environment: string | null;
|
|
191
|
+
rootInstance: string | null;
|
|
192
|
+
rootHost: string | null;
|
|
193
|
+
spanCount: number;
|
|
194
|
+
errorCount: number;
|
|
195
|
+
services: string[];
|
|
196
|
+
}
|
|
197
|
+
export interface SpanEvent {
|
|
198
|
+
name: string;
|
|
199
|
+
at: string;
|
|
200
|
+
attributes: Record<string, string>;
|
|
201
|
+
}
|
|
202
|
+
export interface SpanTarget {
|
|
203
|
+
kind: 'service' | 'resource';
|
|
204
|
+
id: string;
|
|
205
|
+
name: string;
|
|
206
|
+
}
|
|
207
|
+
export interface Span {
|
|
208
|
+
spanId: string;
|
|
209
|
+
parentSpanId: string | null;
|
|
210
|
+
serviceId: string | null;
|
|
211
|
+
service: string;
|
|
212
|
+
environment: string | null;
|
|
213
|
+
instance: string | null;
|
|
214
|
+
host: string | null;
|
|
215
|
+
name: string;
|
|
216
|
+
kind: string;
|
|
217
|
+
startedAt: string;
|
|
218
|
+
durationMs: number;
|
|
219
|
+
status: string;
|
|
220
|
+
statusMessage: string | null;
|
|
221
|
+
scope: string | null;
|
|
222
|
+
scopeVersion: string | null;
|
|
223
|
+
attributes: Record<string, string>;
|
|
224
|
+
events: SpanEvent[];
|
|
225
|
+
links: {
|
|
226
|
+
traceId: string;
|
|
227
|
+
spanId: string;
|
|
228
|
+
}[];
|
|
229
|
+
target: SpanTarget | null;
|
|
230
|
+
}
|
|
231
|
+
export interface Trace {
|
|
232
|
+
traceId: string;
|
|
233
|
+
spans: Span[];
|
|
234
|
+
truncated: boolean;
|
|
235
|
+
}
|
|
236
|
+
export interface LogRecord {
|
|
237
|
+
timestamp: string;
|
|
238
|
+
severity: string;
|
|
239
|
+
severityNumber: number;
|
|
240
|
+
service: string;
|
|
241
|
+
environment: string | null;
|
|
242
|
+
instance: string | null;
|
|
243
|
+
body: string;
|
|
244
|
+
bodyTruncated: boolean;
|
|
245
|
+
traceId: string | null;
|
|
246
|
+
spanId: string | null;
|
|
247
|
+
attributes: Record<string, string>;
|
|
248
|
+
}
|
|
249
|
+
export interface Operation {
|
|
250
|
+
name: string;
|
|
251
|
+
kind: string;
|
|
252
|
+
count: number;
|
|
253
|
+
requestsPerSecond: number;
|
|
254
|
+
errorRate: number;
|
|
255
|
+
p50Ms: number;
|
|
256
|
+
p95Ms: number;
|
|
257
|
+
p99Ms: number;
|
|
258
|
+
lastSeen: string;
|
|
259
|
+
}
|
|
260
|
+
export interface MetricInfo {
|
|
261
|
+
name: string;
|
|
262
|
+
type: string;
|
|
263
|
+
unit: string;
|
|
264
|
+
description: string;
|
|
265
|
+
}
|
|
266
|
+
export interface Point {
|
|
267
|
+
at: string;
|
|
268
|
+
value: number | null;
|
|
269
|
+
}
|
|
270
|
+
export interface Series {
|
|
271
|
+
name: string;
|
|
272
|
+
type: string;
|
|
273
|
+
unit: string;
|
|
274
|
+
aggregation: string;
|
|
275
|
+
stepSeconds: number;
|
|
276
|
+
points: Point[];
|
|
277
|
+
}
|
|
278
|
+
export interface ServiceStatsPoint {
|
|
279
|
+
at: string;
|
|
280
|
+
requestsPerSecond: number;
|
|
281
|
+
errorRate: number;
|
|
282
|
+
p95Ms: number | null;
|
|
283
|
+
}
|
|
284
|
+
export interface ServiceStats {
|
|
285
|
+
stepSeconds: number;
|
|
286
|
+
points: ServiceStatsPoint[];
|
|
287
|
+
}
|
|
288
|
+
export interface DependencyEvidence {
|
|
289
|
+
dependencyId: string;
|
|
290
|
+
relation: string;
|
|
291
|
+
confidence: string;
|
|
292
|
+
count: number;
|
|
293
|
+
errorRate: number;
|
|
294
|
+
p95Ms: number | null;
|
|
295
|
+
lastSeen: string | null;
|
|
296
|
+
slowestTraces: string[];
|
|
297
|
+
errorTraces: string[];
|
|
298
|
+
}
|
|
299
|
+
export interface SearchHit {
|
|
300
|
+
kind: 'trace' | 'span' | 'service';
|
|
301
|
+
id: string;
|
|
302
|
+
title: string;
|
|
303
|
+
traceId: string | null;
|
|
304
|
+
}
|
|
305
|
+
export type Query = Record<string, string | number | boolean | string[] | null | undefined>;
|
|
306
|
+
/**
|
|
307
|
+
* The Console's only backend: the Juice API (Console requirements §3). One deployment serves one tenant, the one the
|
|
308
|
+
* signed-in user's token names.
|
|
309
|
+
*/
|
|
310
|
+
export declare class ApiService {
|
|
311
|
+
private readonly http;
|
|
312
|
+
private readonly base;
|
|
313
|
+
/** The caller's tenant, fetched once. */
|
|
314
|
+
readonly tenant$: Observable<Tenant>;
|
|
315
|
+
private get;
|
|
316
|
+
/** Every page of a cursor-paged list (bounded: at most `maxPages` requests). */
|
|
317
|
+
private all;
|
|
318
|
+
environments(): Observable<Page<DeploymentEnvironment>>;
|
|
319
|
+
applications(): Observable<Page<Application>>;
|
|
320
|
+
resources(type?: string): Observable<Page<ResourceSummary>>;
|
|
321
|
+
resource(id: string): Observable<ResourceDetail>;
|
|
322
|
+
health(query: Query): Observable<Page<Health>>;
|
|
323
|
+
topology(environment?: string | null): Observable<Topology>;
|
|
324
|
+
rules(): Observable<Page<Rule>>;
|
|
325
|
+
/** One page of alerts, newest first; pass the previous page's `nextCursor` as `cursor` for the next. */
|
|
326
|
+
alerts(query: Query): Observable<Page<Alert>>;
|
|
327
|
+
/** Every alert matching the query (bounded, like the other complete lists). */
|
|
328
|
+
allAlerts(query: Query): Observable<Page<Alert>>;
|
|
329
|
+
alert(id: string): Observable<AlertDetail>;
|
|
330
|
+
acknowledge(id: string, comment: string): Observable<Alert>;
|
|
331
|
+
traces(query: Query): Observable<TelemetryPage<TraceSummary>>;
|
|
332
|
+
trace(traceId: string): Observable<Trace>;
|
|
333
|
+
logs(query: Query): Observable<TelemetryPage<LogRecord>>;
|
|
334
|
+
operations(query: Query): Observable<TelemetryPage<Operation>>;
|
|
335
|
+
metrics(query: Query): Observable<TelemetryPage<MetricInfo>>;
|
|
336
|
+
series(query: Query): Observable<Series>;
|
|
337
|
+
serviceStats(query: Query): Observable<ServiceStats>;
|
|
338
|
+
dependency(id: string, query: Query): Observable<DependencyEvidence>;
|
|
339
|
+
search(q: string): Observable<TelemetryPage<SearchHit>>;
|
|
340
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ApiService, never>;
|
|
341
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
342
|
+
}
|
|
343
|
+
export declare const RANGES: Record<string, number>;
|
|
344
|
+
/** Search ranges are at most 24 hours (the API's bound); series and operations take up to 7 days. */
|
|
345
|
+
export declare const MAX_SEARCH_MS: number;
|
|
346
|
+
/**
|
|
347
|
+
* The investigation context that follows the user between pages (Console requirements §17): environment and time
|
|
348
|
+
* range. It lives in the URL (`env`, and `range` or `from`/`to`), so every page is a deep link and the browser's back
|
|
349
|
+
* button restores it.
|
|
350
|
+
*/
|
|
351
|
+
export declare class ContextService {
|
|
352
|
+
private readonly router;
|
|
353
|
+
private readonly params;
|
|
354
|
+
readonly environment: import("@angular/core").Signal<string>;
|
|
355
|
+
readonly range: import("@angular/core").Signal<string>;
|
|
356
|
+
readonly absolute: import("@angular/core").Signal<{
|
|
357
|
+
from: string;
|
|
358
|
+
to: string;
|
|
359
|
+
} | null>;
|
|
360
|
+
/** The window as ISO strings, evaluated now for a relative range. */
|
|
361
|
+
window(maxMs?: number): {
|
|
362
|
+
from: string;
|
|
363
|
+
to: string;
|
|
364
|
+
};
|
|
365
|
+
/** Query parameters for a link: the context plus the target page's own. */
|
|
366
|
+
keep(extra?: Params): Params;
|
|
367
|
+
/** Changes the context on the current page, keeping its other parameters. */
|
|
368
|
+
set(change: {
|
|
369
|
+
env?: string | null;
|
|
370
|
+
range?: string | null;
|
|
371
|
+
from?: string | null;
|
|
372
|
+
to?: string | null;
|
|
373
|
+
}): void;
|
|
374
|
+
/** A time window centred on a moment, for "around this span" links. */
|
|
375
|
+
around(at: string, durationMs: number, paddingMs?: number): Params;
|
|
376
|
+
private leaf;
|
|
377
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ContextService, never>;
|
|
378
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* The pages, investigation first (Console requirements §4): services, traces, topology, logs and metrics; alerts and
|
|
382
|
+
* rules after. Detail pages are deep links (§17) and carry the environment and time range in their query parameters.
|
|
383
|
+
* The host mounts them at its `basePath` (see {@link provideJuiceObservability}) and adds its own guards.
|
|
384
|
+
*/
|
|
385
|
+
export declare const OBSERVABILITY_ROUTES: Routes;
|
|
386
|
+
/** The side menu entries (juice-layout), investigation pages first, linking under `basePath`. */
|
|
387
|
+
export declare function observabilityMenus(basePath?: string, order?: number): Menus;
|