log10x-mcp 1.0.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -0
  3. package/build/index.d.ts +8 -0
  4. package/build/index.js +150 -0
  5. package/build/index.js.map +1 -0
  6. package/build/lib/api.d.ts +31 -0
  7. package/build/lib/api.js +89 -0
  8. package/build/lib/api.js.map +1 -0
  9. package/build/lib/cost.d.ts +14 -0
  10. package/build/lib/cost.js +23 -0
  11. package/build/lib/cost.js.map +1 -0
  12. package/build/lib/environments.d.ts +24 -0
  13. package/build/lib/environments.js +51 -0
  14. package/build/lib/environments.js.map +1 -0
  15. package/build/lib/format.d.ts +29 -0
  16. package/build/lib/format.js +90 -0
  17. package/build/lib/format.js.map +1 -0
  18. package/build/lib/gates.d.ts +23 -0
  19. package/build/lib/gates.js +29 -0
  20. package/build/lib/gates.js.map +1 -0
  21. package/build/lib/promql.d.ts +43 -0
  22. package/build/lib/promql.js +99 -0
  23. package/build/lib/promql.js.map +1 -0
  24. package/build/lib/resolve-env.d.ts +11 -0
  25. package/build/lib/resolve-env.js +35 -0
  26. package/build/lib/resolve-env.js.map +1 -0
  27. package/build/resources/status.d.ts +7 -0
  28. package/build/resources/status.js +37 -0
  29. package/build/resources/status.js.map +1 -0
  30. package/build/tools/cost-drivers.d.ts +28 -0
  31. package/build/tools/cost-drivers.js +142 -0
  32. package/build/tools/cost-drivers.js.map +1 -0
  33. package/build/tools/dependency-check.d.ts +22 -0
  34. package/build/tools/dependency-check.js +80 -0
  35. package/build/tools/dependency-check.js.map +1 -0
  36. package/build/tools/event-lookup.d.ts +23 -0
  37. package/build/tools/event-lookup.js +131 -0
  38. package/build/tools/event-lookup.js.map +1 -0
  39. package/build/tools/exclusion-filter.d.ts +21 -0
  40. package/build/tools/exclusion-filter.js +246 -0
  41. package/build/tools/exclusion-filter.js.map +1 -0
  42. package/build/tools/savings.d.ts +17 -0
  43. package/build/tools/savings.js +75 -0
  44. package/build/tools/savings.js.map +1 -0
  45. package/build/tools/services.d.ts +14 -0
  46. package/build/tools/services.js +53 -0
  47. package/build/tools/services.js.map +1 -0
  48. package/build/tools/trend.d.ts +20 -0
  49. package/build/tools/trend.js +122 -0
  50. package/build/tools/trend.js.map +1 -0
  51. package/package.json +56 -0
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Output formatting helpers.
3
+ *
4
+ * Plain text, not markdown. Dollar amounts are prominent.
5
+ * Designed for AI consumption — concise, structured, parseable.
6
+ */
7
+ /** Format a dollar amount: $1.2K, $14K, $1.2M, etc. */
8
+ export function fmtDollar(amount) {
9
+ const abs = Math.abs(amount);
10
+ const sign = amount < 0 ? '-' : '';
11
+ if (abs < 1)
12
+ return `${sign}$${abs.toFixed(2)}`;
13
+ if (abs < 10)
14
+ return `${sign}$${abs.toFixed(1)}`;
15
+ if (abs < 1000)
16
+ return `${sign}$${Math.round(abs)}`;
17
+ if (abs < 10000)
18
+ return `${sign}$${(abs / 1000).toFixed(1)}K`;
19
+ if (abs < 1000000)
20
+ return `${sign}$${Math.round(abs / 1000)}K`;
21
+ return `${sign}$${(abs / 1000000).toFixed(1)}M`;
22
+ }
23
+ /** Format bytes as human-readable: 1.2 GB, 450 MB, etc. */
24
+ export function fmtBytes(bytes) {
25
+ const abs = Math.abs(bytes);
26
+ if (abs < 1024)
27
+ return `${Math.round(abs)} B`;
28
+ if (abs < 1024 * 1024)
29
+ return `${(abs / 1024).toFixed(1)} KB`;
30
+ if (abs < 1024 * 1024 * 1024)
31
+ return `${(abs / (1024 * 1024)).toFixed(1)} MB`;
32
+ if (abs < 1024 * 1024 * 1024 * 1024)
33
+ return `${(abs / (1024 * 1024 * 1024)).toFixed(1)} GB`;
34
+ return `${(abs / (1024 * 1024 * 1024 * 1024)).toFixed(1)} TB`;
35
+ }
36
+ /** Format event count: 1.2B, 450M, 12K, etc. */
37
+ export function fmtCount(count) {
38
+ const abs = Math.abs(count);
39
+ if (abs < 1000)
40
+ return `${Math.round(abs)}`;
41
+ if (abs < 1000000)
42
+ return `${(abs / 1000).toFixed(abs < 10000 ? 1 : 0)}K`;
43
+ if (abs < 1000000000)
44
+ return `${(abs / 1000000).toFixed(abs < 10000000 ? 1 : 0)}M`;
45
+ return `${(abs / 1000000000).toFixed(1)}B`;
46
+ }
47
+ /** Format a pattern name for display: replace underscores with spaces. */
48
+ export function fmtPattern(pattern) {
49
+ return pattern.replace(/_/g, ' ');
50
+ }
51
+ /** Format severity: first 4 chars uppercase. */
52
+ export function fmtSeverity(sev) {
53
+ return sev.toUpperCase().slice(0, 4);
54
+ }
55
+ /** Format a percentage. */
56
+ export function fmtPct(value) {
57
+ if (value < 1)
58
+ return `${value.toFixed(1)}%`;
59
+ return `${Math.round(value)}%`;
60
+ }
61
+ /** Parse a timeframe string (1d, 7d, 30d) into a Timeframe config. */
62
+ export function parseTimeframe(input) {
63
+ const match = input.match(/^(\d+)d$/);
64
+ if (!match)
65
+ throw new Error(`Invalid timeframe: ${input}`);
66
+ const days = parseInt(match[1], 10);
67
+ if (days < 1 || days > 90)
68
+ throw new Error(`Timeframe must be 1-90 days, got ${days}`);
69
+ let label;
70
+ if (days === 1)
71
+ label = 'last 24h';
72
+ else if (days === 7)
73
+ label = 'this week';
74
+ else
75
+ label = `last ${days}d`;
76
+ // Baseline: 3 prior windows of same size
77
+ const baselineOffsets = [days, days * 2, days * 3];
78
+ return { days, range: `${days}d`, label, baselineOffsets };
79
+ }
80
+ /** Cost period label for output. */
81
+ export function costPeriodLabel(days) {
82
+ if (days === 1)
83
+ return '/day';
84
+ if (days === 7)
85
+ return '/wk';
86
+ if (days === 30)
87
+ return '/mo';
88
+ return `/${days}d`;
89
+ }
90
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Cost driver gates.
3
+ *
4
+ * A pattern is a cost driver only if BOTH gates pass:
5
+ * 1. Dollar delta > minDollarPerWeek (default $500/wk)
6
+ * 2. Contribution > minContributionPct of total positive delta (default 5%)
7
+ *
8
+ * These are business rules, not statistical constants.
9
+ * Ported from SlackPatternService.java.
10
+ */
11
+ export interface PatternWithDelta {
12
+ delta: number;
13
+ }
14
+ export interface GateConfig {
15
+ minDollarPerWeek: number;
16
+ minContributionPct: number;
17
+ }
18
+ export declare const DEFAULT_GATES: GateConfig;
19
+ /**
20
+ * Filters patterns through cost driver gates.
21
+ * Returns only patterns that pass both the dollar floor and contribution % gate.
22
+ */
23
+ export declare function applyCostDriverGates<T extends PatternWithDelta>(patterns: T[], totalPositiveDelta: number, gates?: GateConfig): T[];
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Cost driver gates.
3
+ *
4
+ * A pattern is a cost driver only if BOTH gates pass:
5
+ * 1. Dollar delta > minDollarPerWeek (default $500/wk)
6
+ * 2. Contribution > minContributionPct of total positive delta (default 5%)
7
+ *
8
+ * These are business rules, not statistical constants.
9
+ * Ported from SlackPatternService.java.
10
+ */
11
+ export const DEFAULT_GATES = {
12
+ minDollarPerWeek: 500,
13
+ minContributionPct: 5,
14
+ };
15
+ /**
16
+ * Filters patterns through cost driver gates.
17
+ * Returns only patterns that pass both the dollar floor and contribution % gate.
18
+ */
19
+ export function applyCostDriverGates(patterns, totalPositiveDelta, gates = DEFAULT_GATES) {
20
+ return patterns.filter(p => {
21
+ if (p.delta <= 0)
22
+ return false;
23
+ const passesDollar = p.delta >= gates.minDollarPerWeek;
24
+ const passesContrib = totalPositiveDelta > 0
25
+ && (p.delta / totalPositiveDelta) * 100 >= gates.minContributionPct;
26
+ return passesDollar && passesContrib;
27
+ });
28
+ }
29
+ //# sourceMappingURL=gates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/lib/gates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,MAAM,CAAC,MAAM,aAAa,GAAe;IACvC,gBAAgB,EAAE,GAAG;IACrB,kBAAkB,EAAE,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAa,EACb,kBAA0B,EAC1B,QAAoB,aAAa;IAEjC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACzB,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/B,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,gBAAgB,CAAC;QACvD,MAAM,aAAa,GAAG,kBAAkB,GAAG,CAAC;eACvC,CAAC,CAAC,CAAC,KAAK,GAAG,kBAAkB,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,kBAAkB,CAAC;QACtE,OAAO,YAAY,IAAI,aAAa,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * PromQL query builders.
3
+ *
4
+ * Generates the PromQL queries used by each tool, matching the patterns
5
+ * in SlackPatternService.java.
6
+ */
7
+ export declare const LABELS: {
8
+ readonly pattern: "message_pattern";
9
+ readonly service: "tenx_user_service";
10
+ readonly severity: "severity_level";
11
+ readonly env: "tenx_env";
12
+ };
13
+ /** Bytes per pattern for a time window, with optional offset in days. */
14
+ export declare function bytesPerPattern(filters: Record<string, string>, env: string, range: string, offsetDays?: number): string;
15
+ /** Event count per pattern for a time window. */
16
+ export declare function eventsPerPattern(filters: Record<string, string>, env: string, range: string): string;
17
+ /** Event count per service for a specific pattern. */
18
+ export declare function eventsPerServiceForPattern(pattern: string, env: string, range: string): string;
19
+ /** Top N patterns by bytes across all services. */
20
+ export declare function topPatterns(env: string, range: string, limit: number): string;
21
+ /** Bytes per service for a specific pattern. */
22
+ export declare function patternAcrossServices(pattern: string, env: string, range: string, offsetDays?: number): string;
23
+ /** Total bytes for a time window. */
24
+ export declare function totalBytes(env: string, range: string): string;
25
+ /** Bytes per service. */
26
+ export declare function bytesPerService(env: string, range: string): string;
27
+ /** Bytes per severity. */
28
+ export declare function bytesPerSeverity(env: string, range: string): string;
29
+ /** Pattern bytes over time (for range queries / trends). */
30
+ export declare function patternBytesOverTime(pattern: string, env: string, step: string): string;
31
+ /** Probe: does edge env have data? */
32
+ export declare function edgeProbe(): string;
33
+ /** Probe: does edge env have data for specific filters? */
34
+ export declare function edgeProbeFiltered(filters: Record<string, string>): string;
35
+ /** Pipeline instance count. */
36
+ export declare function pipelineUp(): string;
37
+ /** Distinct services with data. */
38
+ export declare function distinctServices(range: string): string;
39
+ export declare function regulatorInput(range: string): string;
40
+ export declare function regulatorOutput(range: string): string;
41
+ export declare function optimizerInput(range: string): string;
42
+ export declare function optimizerOutput(range: string): string;
43
+ export declare function streamerIndexed(range: string): string;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * PromQL query builders.
3
+ *
4
+ * Generates the PromQL queries used by each tool, matching the patterns
5
+ * in SlackPatternService.java.
6
+ */
7
+ const BYTES_METRIC = 'all_events_summaryBytes_total';
8
+ const VOLUME_METRIC = 'all_events_summaryVolume_total';
9
+ export const LABELS = {
10
+ pattern: 'message_pattern',
11
+ service: 'tenx_user_service',
12
+ severity: 'severity_level',
13
+ env: 'tenx_env',
14
+ };
15
+ function escapeLabel(value) {
16
+ return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
17
+ }
18
+ function buildSelector(filters, env) {
19
+ const parts = [];
20
+ for (const [key, value] of Object.entries(filters)) {
21
+ parts.push(`${key}="${escapeLabel(value)}"`);
22
+ }
23
+ parts.push(`${LABELS.env}="${env}"`);
24
+ return parts.join(',');
25
+ }
26
+ /** Bytes per pattern for a time window, with optional offset in days. */
27
+ export function bytesPerPattern(filters, env, range, offsetDays) {
28
+ const offset = offsetDays ? ` offset ${offsetDays}d` : '';
29
+ const selector = buildSelector(filters, env);
30
+ return `sum by (${LABELS.pattern}, ${LABELS.service}, ${LABELS.severity}) (increase(${BYTES_METRIC}{${selector}}[${range}]${offset}))`;
31
+ }
32
+ /** Event count per pattern for a time window. */
33
+ export function eventsPerPattern(filters, env, range) {
34
+ const selector = buildSelector(filters, env);
35
+ return `sum by (${LABELS.pattern}) (increase(${VOLUME_METRIC}{${selector}}[${range}]))`;
36
+ }
37
+ /** Event count per service for a specific pattern. */
38
+ export function eventsPerServiceForPattern(pattern, env, range) {
39
+ return `sum by (${LABELS.service}) (increase(${VOLUME_METRIC}{${LABELS.pattern}="${escapeLabel(pattern)}",${LABELS.env}="${env}"}[${range}]))`;
40
+ }
41
+ /** Top N patterns by bytes across all services. */
42
+ export function topPatterns(env, range, limit) {
43
+ return `topk(${limit}, sum by (${LABELS.pattern}, ${LABELS.service}, ${LABELS.severity}) (increase(${BYTES_METRIC}{${LABELS.env}="${env}"}[${range}])))`;
44
+ }
45
+ /** Bytes per service for a specific pattern. */
46
+ export function patternAcrossServices(pattern, env, range, offsetDays) {
47
+ const offset = offsetDays ? ` offset ${offsetDays}d` : '';
48
+ return `sum by (${LABELS.service}, ${LABELS.severity}) (increase(${BYTES_METRIC}{${LABELS.pattern}="${escapeLabel(pattern)}",${LABELS.env}="${env}"}[${range}]${offset}))`;
49
+ }
50
+ /** Total bytes for a time window. */
51
+ export function totalBytes(env, range) {
52
+ return `sum(increase(${BYTES_METRIC}{${LABELS.env}="${env}"}[${range}]))`;
53
+ }
54
+ /** Bytes per service. */
55
+ export function bytesPerService(env, range) {
56
+ return `sort_desc(sum by (${LABELS.service}) (increase(${BYTES_METRIC}{${LABELS.env}="${env}"}[${range}])))`;
57
+ }
58
+ /** Bytes per severity. */
59
+ export function bytesPerSeverity(env, range) {
60
+ return `sum by (${LABELS.severity}) (increase(${BYTES_METRIC}{${LABELS.env}="${env}"}[${range}]))`;
61
+ }
62
+ /** Pattern bytes over time (for range queries / trends). */
63
+ export function patternBytesOverTime(pattern, env, step) {
64
+ return `sum by (${LABELS.pattern}) (increase(${BYTES_METRIC}{${LABELS.env}="${env}",${LABELS.pattern}="${escapeLabel(pattern)}"}[${step}]))`;
65
+ }
66
+ /** Probe: does edge env have data? */
67
+ export function edgeProbe() {
68
+ return `count(increase(${BYTES_METRIC}{${LABELS.env}="edge"}[7d]) > 0)`;
69
+ }
70
+ /** Probe: does edge env have data for specific filters? */
71
+ export function edgeProbeFiltered(filters) {
72
+ const selector = buildSelector(filters, 'edge');
73
+ return `count(increase(${BYTES_METRIC}{${selector}}[7d]) > 0)`;
74
+ }
75
+ /** Pipeline instance count. */
76
+ export function pipelineUp() {
77
+ return 'count(tenx_pipeline_up)';
78
+ }
79
+ /** Distinct services with data. */
80
+ export function distinctServices(range) {
81
+ return `count(count by (${LABELS.service}) (increase(${BYTES_METRIC}[${range}]) > 0))`;
82
+ }
83
+ // ── Savings queries (regulator, optimizer, streamer) ──
84
+ export function regulatorInput(range) {
85
+ return `sum(increase(${BYTES_METRIC}{tenx_app="regulator",${LABELS.env}="edge"}[${range}]))`;
86
+ }
87
+ export function regulatorOutput(range) {
88
+ return `sum(increase(${BYTES_METRIC}{tenx_app=~"regulator|optimizer",${LABELS.env}="edge"}[${range}]))`;
89
+ }
90
+ export function optimizerInput(range) {
91
+ return `sum(increase(${BYTES_METRIC}{tenx_app="optimizer",tenx_env="edge",tenx_stage="input"}[${range}]))`;
92
+ }
93
+ export function optimizerOutput(range) {
94
+ return `sum(increase(${BYTES_METRIC}{tenx_app="optimizer",tenx_env="edge",tenx_stage="output"}[${range}]))`;
95
+ }
96
+ export function streamerIndexed(range) {
97
+ return `sum(increase(${BYTES_METRIC}{tenx_app="streamer",${LABELS.env}="cloud"}[${range}]))`;
98
+ }
99
+ //# sourceMappingURL=promql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promql.js","sourceRoot":"","sources":["../../src/lib/promql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Edge/cloud environment resolution.
3
+ *
4
+ * Prefers edge reporter metrics when available, falls back to cloud.
5
+ * Matches resolveEnv/resolveEnvAll in SlackPatternService.java.
6
+ */
7
+ import type { EnvConfig } from './environments.js';
8
+ /** Resolve whether to use edge or cloud metrics (global). */
9
+ export declare function resolveMetricsEnv(env: EnvConfig): Promise<'edge' | 'cloud'>;
10
+ /** Resolve whether to use edge or cloud metrics for specific filters. */
11
+ export declare function resolveMetricsEnvFiltered(env: EnvConfig, filters: Record<string, string>): Promise<'edge' | 'cloud'>;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Edge/cloud environment resolution.
3
+ *
4
+ * Prefers edge reporter metrics when available, falls back to cloud.
5
+ * Matches resolveEnv/resolveEnvAll in SlackPatternService.java.
6
+ */
7
+ import { queryInstant } from './api.js';
8
+ import * as pql from './promql.js';
9
+ /** Resolve whether to use edge or cloud metrics (global). */
10
+ export async function resolveMetricsEnv(env) {
11
+ try {
12
+ const res = await queryInstant(env, pql.edgeProbe());
13
+ if (res.status === 'success' && res.data.result.length > 0) {
14
+ return 'edge';
15
+ }
16
+ }
17
+ catch {
18
+ // fall through to cloud
19
+ }
20
+ return 'cloud';
21
+ }
22
+ /** Resolve whether to use edge or cloud metrics for specific filters. */
23
+ export async function resolveMetricsEnvFiltered(env, filters) {
24
+ try {
25
+ const res = await queryInstant(env, pql.edgeProbeFiltered(filters));
26
+ if (res.status === 'success' && res.data.result.length > 0) {
27
+ return 'edge';
28
+ }
29
+ }
30
+ catch {
31
+ // fall through to cloud
32
+ }
33
+ return 'cloud';
34
+ }
35
+ //# sourceMappingURL=resolve-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-env.js","sourceRoot":"","sources":["../../src/lib/resolve-env.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AAEnC,6DAA6D;AAC7D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAc;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACrD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3D,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,GAAc,EACd,OAA+B;IAE/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;QACpE,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3D,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * log10x://status resource — pipeline health summary.
3
+ *
4
+ * AI assistants can read this for context before answering questions.
5
+ */
6
+ import type { EnvConfig } from '../lib/environments.js';
7
+ export declare function getStatus(env: EnvConfig): Promise<string>;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * log10x://status resource — pipeline health summary.
3
+ *
4
+ * AI assistants can read this for context before answering questions.
5
+ */
6
+ import { queryInstant } from '../lib/api.js';
7
+ import * as pql from '../lib/promql.js';
8
+ import { parsePrometheusValue, bytesToGb } from '../lib/cost.js';
9
+ import { fmtBytes } from '../lib/format.js';
10
+ import { resolveMetricsEnv } from '../lib/resolve-env.js';
11
+ export async function getStatus(env) {
12
+ const metricsEnv = await resolveMetricsEnv(env);
13
+ const [pipeRes, svcRes, volRes] = await Promise.all([
14
+ queryInstant(env, pql.pipelineUp()).catch(() => null),
15
+ queryInstant(env, pql.distinctServices('24h')).catch(() => null),
16
+ queryInstant(env, pql.totalBytes(metricsEnv, '24h')).catch(() => null),
17
+ ]);
18
+ const pipelines = pipeRes?.data?.result?.[0] ? Math.round(parsePrometheusValue(pipeRes.data.result[0])) : 0;
19
+ const services = svcRes?.data?.result?.[0] ? Math.round(parsePrometheusValue(svcRes.data.result[0])) : 0;
20
+ const vol24h = volRes?.data?.result?.[0] ? parsePrometheusValue(volRes.data.result[0]) : 0;
21
+ const lines = [];
22
+ lines.push('Log10x Pipeline Status');
23
+ lines.push('');
24
+ if (pipelines > 0 || services > 0 || vol24h > 0) {
25
+ lines.push(` Pipeline instances: ${pipelines}`);
26
+ lines.push(` Services monitored: ${services}`);
27
+ lines.push(` Volume (24h): ${fmtBytes(vol24h)} (${bytesToGb(vol24h).toFixed(1)} GB)`);
28
+ lines.push('');
29
+ lines.push(' Status: active');
30
+ }
31
+ else {
32
+ lines.push(' No pipeline data available.');
33
+ lines.push(' Data appears after the first 24h of collection.');
34
+ }
35
+ return lines.join('\n');
36
+ }
37
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/resources/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAc;IAC5C,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;QACrD,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;QAChE,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;KACvE,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5G,MAAM,QAAQ,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzG,MAAM,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3F,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,IAAI,SAAS,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,mBAAmB,QAAQ,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * log10x_cost_drivers — the core attribution tool.
3
+ *
4
+ * Finds patterns whose cost increase exceeds both the dollar floor
5
+ * and contribution gate, ranked by delta. Equivalent to `/log10x {service}`.
6
+ *
7
+ * Algorithm (ported from SlackPatternService.java):
8
+ * 1. Query current window bytes per pattern
9
+ * 2. Query 3 baseline windows (offset N, 2N, 3N days)
10
+ * 3. Compute delta = current cost - avg baseline cost
11
+ * 4. Filter: delta > $500/wk AND delta/totalDelta > 5%
12
+ * 5. Sort by delta descending
13
+ */
14
+ import { z } from 'zod';
15
+ import type { EnvConfig } from '../lib/environments.js';
16
+ export declare const costDriversSchema: {
17
+ service: z.ZodOptional<z.ZodString>;
18
+ timeRange: z.ZodDefault<z.ZodEnum<["1d", "7d", "30d"]>>;
19
+ limit: z.ZodDefault<z.ZodNumber>;
20
+ analyzerCost: z.ZodOptional<z.ZodNumber>;
21
+ environment: z.ZodOptional<z.ZodString>;
22
+ };
23
+ export declare function executeCostDrivers(args: {
24
+ service?: string;
25
+ timeRange: string;
26
+ limit: number;
27
+ analyzerCost: number;
28
+ }, env: EnvConfig): Promise<string>;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * log10x_cost_drivers — the core attribution tool.
3
+ *
4
+ * Finds patterns whose cost increase exceeds both the dollar floor
5
+ * and contribution gate, ranked by delta. Equivalent to `/log10x {service}`.
6
+ *
7
+ * Algorithm (ported from SlackPatternService.java):
8
+ * 1. Query current window bytes per pattern
9
+ * 2. Query 3 baseline windows (offset N, 2N, 3N days)
10
+ * 3. Compute delta = current cost - avg baseline cost
11
+ * 4. Filter: delta > $500/wk AND delta/totalDelta > 5%
12
+ * 5. Sort by delta descending
13
+ */
14
+ import { z } from 'zod';
15
+ import { queryInstant } from '../lib/api.js';
16
+ import * as pql from '../lib/promql.js';
17
+ import { LABELS } from '../lib/promql.js';
18
+ import { bytesToCost, parsePrometheusValue } from '../lib/cost.js';
19
+ import { applyCostDriverGates, DEFAULT_GATES } from '../lib/gates.js';
20
+ import { resolveMetricsEnv, resolveMetricsEnvFiltered } from '../lib/resolve-env.js';
21
+ import { fmtDollar, fmtPattern, fmtSeverity, fmtCount, parseTimeframe, costPeriodLabel } from '../lib/format.js';
22
+ export const costDriversSchema = {
23
+ service: z.string().optional().describe("Service name to filter (e.g., 'checkout'). Omit for all services."),
24
+ timeRange: z.enum(['1d', '7d', '30d']).default('7d').describe('Time range to analyze'),
25
+ limit: z.number().min(1).max(20).default(10).describe('Max patterns to return'),
26
+ analyzerCost: z.number().optional().describe('SIEM ingestion cost in $/GB. Auto-detected from your profile if omitted.'),
27
+ environment: z.string().optional().describe('Environment nickname (for multi-env setups)'),
28
+ };
29
+ export async function executeCostDrivers(args, env) {
30
+ const tf = parseTimeframe(args.timeRange);
31
+ const costPerGb = args.analyzerCost;
32
+ const period = costPeriodLabel(tf.days);
33
+ const filters = {};
34
+ if (args.service)
35
+ filters[LABELS.service] = args.service;
36
+ // Resolve edge vs cloud
37
+ const metricsEnv = Object.keys(filters).length > 0
38
+ ? await resolveMetricsEnvFiltered(env, filters)
39
+ : await resolveMetricsEnv(env);
40
+ // Query 1: current window
41
+ const currentRes = await queryInstant(env, pql.bytesPerPattern(filters, metricsEnv, tf.range));
42
+ if (currentRes.status !== 'success' || currentRes.data.result.length === 0) {
43
+ return 'No pattern data available. Patterns appear after the first 24h of data collection.';
44
+ }
45
+ const currentByHash = new Map();
46
+ for (const r of currentRes.data.result) {
47
+ const hash = r.metric[LABELS.pattern];
48
+ if (!hash)
49
+ continue;
50
+ currentByHash.set(hash, {
51
+ service: r.metric[LABELS.service] || '',
52
+ severity: r.metric[LABELS.severity] || '',
53
+ bytes: parsePrometheusValue(r),
54
+ });
55
+ }
56
+ // Queries 2-4: baseline windows (3 prior periods)
57
+ const baselineByHash = new Map();
58
+ for (const offsetDays of tf.baselineOffsets) {
59
+ const baseRes = await queryInstant(env, pql.bytesPerPattern(filters, metricsEnv, tf.range, offsetDays));
60
+ if (baseRes.status === 'success') {
61
+ for (const r of baseRes.data.result) {
62
+ const hash = r.metric[LABELS.pattern];
63
+ if (!hash)
64
+ continue;
65
+ const arr = baselineByHash.get(hash) || [];
66
+ arr.push(parsePrometheusValue(r));
67
+ baselineByHash.set(hash, arr);
68
+ }
69
+ }
70
+ }
71
+ // Query 5: event counts
72
+ const eventsRes = await queryInstant(env, pql.eventsPerPattern(filters, metricsEnv, tf.range));
73
+ const eventsByHash = new Map();
74
+ if (eventsRes.status === 'success') {
75
+ for (const r of eventsRes.data.result) {
76
+ const hash = r.metric[LABELS.pattern];
77
+ if (hash)
78
+ eventsByHash.set(hash, parsePrometheusValue(r));
79
+ }
80
+ }
81
+ // Build patterns with cost + delta
82
+ const allPatterns = [];
83
+ let totalPositiveDelta = 0;
84
+ for (const [hash, row] of currentByHash) {
85
+ const costNow = bytesToCost(row.bytes, costPerGb);
86
+ const baseWeeks = baselineByHash.get(hash) || [];
87
+ const isNew = baseWeeks.length === 0;
88
+ const costBaseline = isNew ? 0 : bytesToCost(baseWeeks.reduce((a, b) => a + b, 0) / baseWeeks.length, costPerGb);
89
+ const delta = costNow - costBaseline;
90
+ allPatterns.push({
91
+ hash, service: row.service, severity: row.severity,
92
+ costNow, costBaseline, delta, isNew,
93
+ events: eventsByHash.get(hash) || 0,
94
+ });
95
+ if (delta > 0)
96
+ totalPositiveDelta += delta;
97
+ }
98
+ // Sort by delta descending
99
+ allPatterns.sort((a, b) => b.delta - a.delta);
100
+ // Apply cost driver gates
101
+ const drivers = applyCostDriverGates(allPatterns, totalPositiveDelta, DEFAULT_GATES);
102
+ // Format output
103
+ const lines = [];
104
+ const displayName = args.service || 'all services';
105
+ if (drivers.length > 0) {
106
+ const driversCost = drivers.reduce((s, d) => s + d.costNow, 0);
107
+ const baselineCost = drivers.reduce((s, d) => s + d.costBaseline, 0);
108
+ lines.push(`${displayName} — ${fmtDollar(baselineCost)} → ${fmtDollar(driversCost)}${period} (${drivers.length} cost driver${drivers.length > 1 ? 's' : ''})`);
109
+ lines.push('');
110
+ for (let i = 0; i < Math.min(drivers.length, args.limit); i++) {
111
+ const d = drivers[i];
112
+ const name = fmtPattern(d.hash).padEnd(35);
113
+ const costStr = `${fmtDollar(d.costBaseline)} → ${fmtDollar(d.costNow)}${period}`;
114
+ const sev = fmtSeverity(d.severity);
115
+ const newFlag = d.isNew ? ' NEW' : '';
116
+ const evtStr = d.events > 0 ? ` ${fmtCount(d.events)} events` : '';
117
+ lines.push(`#${i + 1} ${name} ${costStr} ${sev}${newFlag}${evtStr}`);
118
+ }
119
+ // Summary line
120
+ const driverPct = totalPositiveDelta > 0
121
+ ? Math.round((drivers.reduce((s, d) => s + d.delta, 0) / totalPositiveDelta) * 100)
122
+ : 0;
123
+ const stableCount = allPatterns.length - drivers.length;
124
+ lines.push('');
125
+ lines.push(`${drivers.length} driver${drivers.length > 1 ? 's' : ''} = ${driverPct}% of increase · ${stableCount} other pattern${stableCount !== 1 ? 's' : ''}`);
126
+ }
127
+ else {
128
+ // No drivers — show top patterns by current cost
129
+ lines.push(`${displayName} — no cost drivers detected (${tf.label})`);
130
+ lines.push(`All ${allPatterns.length} patterns are within normal range.`);
131
+ lines.push('');
132
+ lines.push(`Top patterns by current cost:`);
133
+ const top = allPatterns
134
+ .sort((a, b) => b.costNow - a.costNow)
135
+ .slice(0, Math.min(5, args.limit));
136
+ for (const p of top) {
137
+ lines.push(` ${fmtPattern(p.hash).padEnd(35)} ${fmtDollar(p.costNow)}${period} ${fmtSeverity(p.severity)}`);
138
+ }
139
+ }
140
+ return lines.join('\n');
141
+ }
142
+ //# sourceMappingURL=cost-drivers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-drivers.js","sourceRoot":"","sources":["../../src/tools/cost-drivers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * log10x_dependency_check — generate a SIEM dependency scan command.
3
+ *
4
+ * Returns a bash command that downloads and runs a Python script to check
5
+ * if dashboards, alerts, or saved searches in the user's SIEM reference
6
+ * a given pattern. The command runs locally, read-only. No data sent to Log10x.
7
+ *
8
+ * Ported from GettingStarted.jsx depcheck section.
9
+ */
10
+ import { z } from 'zod';
11
+ export declare const dependencyCheckSchema: {
12
+ pattern: z.ZodString;
13
+ vendor: z.ZodEnum<["datadog", "splunk", "elasticsearch", "cloudwatch"]>;
14
+ service: z.ZodOptional<z.ZodString>;
15
+ severity: z.ZodOptional<z.ZodString>;
16
+ };
17
+ export declare function executeDependencyCheck(args: {
18
+ pattern: string;
19
+ vendor: string;
20
+ service?: string;
21
+ severity?: string;
22
+ }): string;