@kitlangton/motel 0.1.0
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/AGENTS.md +142 -0
- package/LICENSE +21 -0
- package/README.md +199 -0
- package/package.json +92 -0
- package/src/App.tsx +217 -0
- package/src/cli.ts +258 -0
- package/src/config.ts +39 -0
- package/src/daemon.test.ts +59 -0
- package/src/daemon.ts +398 -0
- package/src/domain.ts +233 -0
- package/src/httpApi.ts +384 -0
- package/src/index.tsx +18 -0
- package/src/instructions.ts +72 -0
- package/src/localServer.ts +699 -0
- package/src/locator.ts +138 -0
- package/src/mcp.ts +260 -0
- package/src/motel.ts +86 -0
- package/src/motelClient.ts +201 -0
- package/src/otlp.ts +142 -0
- package/src/queryFilters.ts +39 -0
- package/src/registry.ts +86 -0
- package/src/runtime.ts +38 -0
- package/src/server.ts +10 -0
- package/src/services/LogQueryService.ts +43 -0
- package/src/services/TelemetryStore.ts +1821 -0
- package/src/services/TraceQueryService.ts +71 -0
- package/src/telemetry.test.ts +726 -0
- package/src/ui/ServiceLogs.tsx +112 -0
- package/src/ui/SpanDetail.tsx +134 -0
- package/src/ui/SpanDetailFull.tsx +224 -0
- package/src/ui/SpanDetailPane.tsx +91 -0
- package/src/ui/TraceDetailsPane.tsx +169 -0
- package/src/ui/TraceList.tsx +128 -0
- package/src/ui/Waterfall.tsx +412 -0
- package/src/ui/app/TraceListPane.tsx +34 -0
- package/src/ui/app/TraceWorkspace.tsx +254 -0
- package/src/ui/app/useAppLayout.ts +79 -0
- package/src/ui/app/useTraceScreenData.ts +411 -0
- package/src/ui/format.ts +119 -0
- package/src/ui/primitives.tsx +170 -0
- package/src/ui/state.ts +137 -0
- package/src/ui/theme.ts +153 -0
- package/src/ui/traceDetailsWidth.repro.test.ts +115 -0
- package/src/ui/traceSortNav.repro.seed.ts +62 -0
- package/src/ui/traceSortNav.repro.test.ts +220 -0
- package/src/ui/useKeyboardNav.ts +532 -0
- package/src/ui/waterfallNav.repro.seed.ts +86 -0
- package/src/ui/waterfallNav.repro.test.ts +263 -0
- package/src/ui/waterfallNav.test.ts +422 -0
- package/src/ui/waterfallNav.ts +75 -0
- package/web/dist/assets/index-BEKIiisE.js +27 -0
- package/web/dist/assets/index-DzuHNBGV.css +2 -0
- package/web/dist/index.html +13 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Effect, Layer, Context } from "effect"
|
|
2
|
+
import type { SpanItem, TraceItem, TraceSummaryItem } from "../domain.js"
|
|
3
|
+
import { TelemetryStore } from "./TelemetryStore.js"
|
|
4
|
+
|
|
5
|
+
export class TraceQueryService extends Context.Service<
|
|
6
|
+
TraceQueryService,
|
|
7
|
+
{
|
|
8
|
+
readonly listServices: Effect.Effect<readonly string[], Error>
|
|
9
|
+
readonly listRecentTraces: (serviceName: string, options?: { readonly lookbackMinutes?: number; readonly limit?: number }) => Effect.Effect<readonly TraceItem[], Error>
|
|
10
|
+
readonly listTraceSummaries: (serviceName: string, options?: { readonly lookbackMinutes?: number; readonly limit?: number }) => Effect.Effect<readonly TraceSummaryItem[], Error>
|
|
11
|
+
readonly searchTraces: (input: { readonly serviceName?: string | null; readonly operation?: string | null; readonly status?: "ok" | "error" | null; readonly minDurationMs?: number | null; readonly lookbackMinutes?: number; readonly limit?: number; readonly attributeFilters?: Readonly<Record<string, string>> }) => Effect.Effect<readonly TraceItem[], Error>
|
|
12
|
+
readonly traceStats: (input: { readonly groupBy: string; readonly agg: "count" | "avg_duration" | "p95_duration" | "error_rate"; readonly serviceName?: string | null; readonly operation?: string | null; readonly status?: "ok" | "error" | null; readonly minDurationMs?: number | null; readonly lookbackMinutes?: number; readonly limit?: number; readonly attributeFilters?: Readonly<Record<string, string>> }) => Effect.Effect<readonly { readonly group: string; readonly value: number; readonly count: number }[], Error>
|
|
13
|
+
readonly getTrace: (traceId: string) => Effect.Effect<TraceItem | null, Error>
|
|
14
|
+
readonly getSpan: (spanId: string) => Effect.Effect<SpanItem | null, Error>
|
|
15
|
+
readonly listTraceSpans: (traceId: string) => Effect.Effect<readonly SpanItem[], Error>
|
|
16
|
+
readonly searchSpans: (input: { readonly serviceName?: string | null; readonly operation?: string | null; readonly parentOperation?: string | null; readonly status?: "ok" | "error" | null; readonly lookbackMinutes?: number; readonly limit?: number; readonly attributeFilters?: Readonly<Record<string, string>> }) => Effect.Effect<readonly SpanItem[], Error>
|
|
17
|
+
}
|
|
18
|
+
>()("motel/TraceQueryService") {}
|
|
19
|
+
|
|
20
|
+
export const TraceQueryServiceLive = Layer.effect(
|
|
21
|
+
TraceQueryService,
|
|
22
|
+
Effect.gen(function* () {
|
|
23
|
+
const store = yield* TelemetryStore
|
|
24
|
+
|
|
25
|
+
const listServices = Effect.fn("motel/TraceQueryService.listServices")(function* () {
|
|
26
|
+
const services = yield* store.listServices
|
|
27
|
+
yield* Effect.annotateCurrentSpan("trace.service_count", services.length)
|
|
28
|
+
return services
|
|
29
|
+
})()
|
|
30
|
+
|
|
31
|
+
const listRecentTraces = Effect.fn("motel/TraceQueryService.listRecentTraces")(function* (serviceName: string, options?: { readonly lookbackMinutes?: number; readonly limit?: number }) {
|
|
32
|
+
yield* Effect.annotateCurrentSpan({
|
|
33
|
+
"trace.service_name": serviceName,
|
|
34
|
+
})
|
|
35
|
+
const traces = yield* store.listRecentTraces(serviceName, options)
|
|
36
|
+
yield* Effect.annotateCurrentSpan("trace.result_count", traces.length)
|
|
37
|
+
return traces
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const listTraceSummaries = Effect.fn("motel/TraceQueryService.listTraceSummaries")(function* (serviceName: string, options?: { readonly lookbackMinutes?: number; readonly limit?: number }) {
|
|
41
|
+
yield* Effect.annotateCurrentSpan({
|
|
42
|
+
"trace.service_name": serviceName,
|
|
43
|
+
})
|
|
44
|
+
const traces = yield* store.listTraceSummaries(serviceName, options)
|
|
45
|
+
yield* Effect.annotateCurrentSpan("trace.result_count", traces.length)
|
|
46
|
+
return traces
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const getTrace = Effect.fn("motel/TraceQueryService.getTrace")(function* (traceId: string) {
|
|
50
|
+
yield* Effect.annotateCurrentSpan("trace.trace_id", traceId)
|
|
51
|
+
return yield* store.getTrace(traceId)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const getSpan = Effect.fn("motel/TraceQueryService.getSpan")(function* (spanId: string) {
|
|
55
|
+
yield* Effect.annotateCurrentSpan("trace.span_id", spanId)
|
|
56
|
+
return yield* store.getSpan(spanId)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
return TraceQueryService.of({
|
|
60
|
+
listServices,
|
|
61
|
+
listRecentTraces,
|
|
62
|
+
listTraceSummaries,
|
|
63
|
+
searchTraces: store.searchTraces,
|
|
64
|
+
traceStats: store.traceStats,
|
|
65
|
+
getTrace,
|
|
66
|
+
getSpan,
|
|
67
|
+
listTraceSpans: store.listTraceSpans,
|
|
68
|
+
searchSpans: store.searchSpans,
|
|
69
|
+
})
|
|
70
|
+
}),
|
|
71
|
+
)
|