@prodisco/prometheus-client 0.1.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/LICENSE +21 -0
- package/README.md +212 -0
- package/dist/client.d.ts +119 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +189 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics.d.ts +65 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +150 -0
- package/dist/metrics.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Prodisco
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# @prodisco/prometheus-client
|
|
2
|
+
|
|
3
|
+
Typed Prometheus client with semantic metric discovery for AI agents. Wraps the `prometheus-query` library with a clean TypeScript interface.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Features](#features)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Quick Start](#quick-start)
|
|
10
|
+
- [API Reference](#api-reference)
|
|
11
|
+
- [Types](#types)
|
|
12
|
+
- [Environment Variables](#environment-variables)
|
|
13
|
+
- [License](#license)
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **Semantic Metric Search**: Find metrics by natural language queries (e.g., "memory usage")
|
|
18
|
+
- **Typed Execution**: Full TypeScript support for PromQL execution
|
|
19
|
+
- **Orama Integration**: Uses `@prodisco/search-libs` for fast, indexed metric search
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @prodisco/prometheus-client
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { PrometheusClient, MetricSearchEngine } from '@prodisco/prometheus-client';
|
|
31
|
+
|
|
32
|
+
// Create client and search engine
|
|
33
|
+
const client = new PrometheusClient({ endpoint: 'http://prometheus:9090' });
|
|
34
|
+
const search = new MetricSearchEngine(client);
|
|
35
|
+
|
|
36
|
+
// 1. DISCOVER metrics with semantic search
|
|
37
|
+
const memoryMetrics = await search.search('memory usage');
|
|
38
|
+
console.log(memoryMetrics);
|
|
39
|
+
// [{ name: 'container_memory_working_set_bytes', type: 'gauge', help: 'Current working set in bytes' }, ...]
|
|
40
|
+
|
|
41
|
+
// 2. EXECUTE PromQL with discovered metric names
|
|
42
|
+
const result = await client.executeRange('container_memory_working_set_bytes', {
|
|
43
|
+
start: new Date(Date.now() - 3600000), // 1 hour ago
|
|
44
|
+
end: new Date(),
|
|
45
|
+
step: '5m'
|
|
46
|
+
});
|
|
47
|
+
console.log(result.data);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API Reference
|
|
51
|
+
|
|
52
|
+
### MetricSearchEngine
|
|
53
|
+
|
|
54
|
+
Semantic search for discovering available metrics. **Use this first** before executing queries.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { PrometheusClient, MetricSearchEngine } from '@prodisco/prometheus-client';
|
|
58
|
+
|
|
59
|
+
const client = new PrometheusClient({ endpoint: 'http://prometheus:9090' });
|
|
60
|
+
const search = new MetricSearchEngine(client);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Methods
|
|
64
|
+
|
|
65
|
+
##### `search(query: string, options?: MetricSearchOptions): Promise<MetricInfo[]>`
|
|
66
|
+
|
|
67
|
+
Search metrics by natural language. Searches both metric names AND descriptions.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// Find memory-related metrics
|
|
71
|
+
const metrics = await search.search('memory usage');
|
|
72
|
+
|
|
73
|
+
// Find CPU metrics, filter by type
|
|
74
|
+
const gauges = await search.search('cpu', { type: 'gauge', limit: 10 });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
##### `index(force?: boolean): Promise<number>`
|
|
78
|
+
|
|
79
|
+
Manually index/refresh metrics from Prometheus. Called automatically on first search.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const count = await search.index();
|
|
83
|
+
console.log(`Indexed ${count} metrics`);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
##### `list(options?: MetricSearchOptions): Promise<MetricInfo[]>`
|
|
87
|
+
|
|
88
|
+
List all indexed metrics.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const allMetrics = await search.list({ limit: 100 });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### PrometheusClient
|
|
95
|
+
|
|
96
|
+
Execute PromQL queries against Prometheus. **Note**: You should know the metric names first - use `MetricSearchEngine.search()` to discover them.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { PrometheusClient } from '@prodisco/prometheus-client';
|
|
100
|
+
|
|
101
|
+
const client = new PrometheusClient({
|
|
102
|
+
endpoint: 'http://prometheus:9090',
|
|
103
|
+
timeout: 30000, // optional, default 30s
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Methods
|
|
108
|
+
|
|
109
|
+
##### `execute(promql: string, time?: Date): Promise<InstantQueryResult>`
|
|
110
|
+
|
|
111
|
+
Execute an instant PromQL query.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// First discover metrics: await search.search('http requests')
|
|
115
|
+
// Then execute with known metric name:
|
|
116
|
+
const result = await client.execute('http_requests_total');
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
##### `executeRange(promql: string, range: TimeRange): Promise<RangeQueryResult>`
|
|
120
|
+
|
|
121
|
+
Execute a range PromQL query over a time period.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// First discover metrics: await search.search('memory')
|
|
125
|
+
// Then execute with known metric name:
|
|
126
|
+
const result = await client.executeRange('node_memory_MemTotal_bytes', {
|
|
127
|
+
start: new Date(Date.now() - 3600000), // 1 hour ago
|
|
128
|
+
end: new Date(),
|
|
129
|
+
step: '5m',
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
result.data.forEach(series => {
|
|
133
|
+
console.log(`Labels: ${JSON.stringify(series.labels)}`);
|
|
134
|
+
series.samples.forEach(s => {
|
|
135
|
+
console.log(` ${new Date(s.time * 1000)}: ${s.value}`);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
##### `listMetrics(): Promise<MetricInfo[]>`
|
|
141
|
+
|
|
142
|
+
Get raw metric metadata from Prometheus. For semantic search, use `MetricSearchEngine` instead.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const metrics = await client.listMetrics();
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
##### `labelNames(): Promise<string[]>`
|
|
149
|
+
|
|
150
|
+
Get all label names.
|
|
151
|
+
|
|
152
|
+
##### `labelValues(label: string): Promise<string[]>`
|
|
153
|
+
|
|
154
|
+
Get all values for a specific label.
|
|
155
|
+
|
|
156
|
+
##### `isHealthy(): Promise<boolean>`
|
|
157
|
+
|
|
158
|
+
Check if Prometheus is reachable.
|
|
159
|
+
|
|
160
|
+
### Helper Function
|
|
161
|
+
|
|
162
|
+
##### `createMetricSearchEngine(endpoint: string): MetricSearchEngine`
|
|
163
|
+
|
|
164
|
+
Create a MetricSearchEngine directly from an endpoint.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
import { createMetricSearchEngine } from '@prodisco/prometheus-client';
|
|
168
|
+
|
|
169
|
+
const search = createMetricSearchEngine('http://prometheus:9090');
|
|
170
|
+
const metrics = await search.search('disk usage');
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Types
|
|
174
|
+
|
|
175
|
+
### MetricInfo
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
interface MetricInfo {
|
|
179
|
+
name: string; // Metric name (e.g., "http_requests_total")
|
|
180
|
+
type: MetricType; // 'counter' | 'gauge' | 'histogram' | 'summary' | 'unknown'
|
|
181
|
+
help: string; // Description
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### MetricSearchOptions
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
interface MetricSearchOptions {
|
|
189
|
+
limit?: number; // Max results (default: 20)
|
|
190
|
+
type?: MetricType; // Filter by metric type
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### TimeRange
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
interface TimeRange {
|
|
198
|
+
start: Date | number; // Start time
|
|
199
|
+
end: Date | number; // End time
|
|
200
|
+
step: string; // Step interval (e.g., "15s", "1m", "5m")
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Environment Variables
|
|
205
|
+
|
|
206
|
+
| Variable | Description | Default |
|
|
207
|
+
|----------|-------------|---------|
|
|
208
|
+
| `PROMETHEUS_URL` | Prometheus server endpoint | - |
|
|
209
|
+
|
|
210
|
+
## License
|
|
211
|
+
|
|
212
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrometheusClient - Typed wrapper around prometheus-query library
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: This client executes PromQL queries. To DISCOVER available metrics,
|
|
5
|
+
* use MetricSearchEngine.search() first.
|
|
6
|
+
*/
|
|
7
|
+
import type { PrometheusClientOptions, TimeRange, InstantQueryResult, RangeQueryResult, MetricInfo } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Typed client for executing PromQL queries against Prometheus.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: This client runs PromQL expressions. To discover available metrics,
|
|
12
|
+
* use MetricSearchEngine.search() - it provides semantic search over metric
|
|
13
|
+
* names and descriptions.
|
|
14
|
+
*/
|
|
15
|
+
export declare class PrometheusClient {
|
|
16
|
+
private options;
|
|
17
|
+
private driver;
|
|
18
|
+
constructor(options: PrometheusClientOptions);
|
|
19
|
+
/**
|
|
20
|
+
* Get the Prometheus endpoint URL
|
|
21
|
+
*/
|
|
22
|
+
getEndpoint(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Initialize the Prometheus driver
|
|
25
|
+
*/
|
|
26
|
+
private getDriver;
|
|
27
|
+
/**
|
|
28
|
+
* Execute an instant PromQL query.
|
|
29
|
+
*
|
|
30
|
+
* This runs a PromQL expression and returns the current value.
|
|
31
|
+
* You must already know the metric name - use MetricSearchEngine.search()
|
|
32
|
+
* to discover available metrics first.
|
|
33
|
+
*
|
|
34
|
+
* @param promql - PromQL expression (e.g., "node_memory_MemTotal_bytes")
|
|
35
|
+
* @param time - Optional evaluation time (defaults to now)
|
|
36
|
+
* @returns Query result with time series data
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // First discover metrics with MetricSearchEngine.search("memory")
|
|
40
|
+
* // Then execute with known metric name:
|
|
41
|
+
* const result = await client.execute("node_memory_MemTotal_bytes");
|
|
42
|
+
*/
|
|
43
|
+
execute(promql: string, time?: Date): Promise<InstantQueryResult>;
|
|
44
|
+
/**
|
|
45
|
+
* Execute a range PromQL query over a time period.
|
|
46
|
+
*
|
|
47
|
+
* This runs a PromQL expression over a time range and returns samples.
|
|
48
|
+
* You must already know the metric name - use MetricSearchEngine.search()
|
|
49
|
+
* to discover available metrics first.
|
|
50
|
+
*
|
|
51
|
+
* @param promql - PromQL expression (e.g., "rate(http_requests_total[5m])")
|
|
52
|
+
* @param range - Time range with start, end, and step
|
|
53
|
+
* @returns Query result with time series data
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // First discover metrics with MetricSearchEngine.search("memory")
|
|
57
|
+
* // Then execute with known metric name:
|
|
58
|
+
* const result = await client.executeRange("node_memory_MemTotal_bytes", {
|
|
59
|
+
* start: new Date(Date.now() - 3600000),
|
|
60
|
+
* end: new Date(),
|
|
61
|
+
* step: "5m"
|
|
62
|
+
* });
|
|
63
|
+
*/
|
|
64
|
+
executeRange(promql: string, range: TimeRange): Promise<RangeQueryResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Get all label names
|
|
67
|
+
*/
|
|
68
|
+
labelNames(): Promise<string[]>;
|
|
69
|
+
/**
|
|
70
|
+
* Get all values for a label
|
|
71
|
+
*
|
|
72
|
+
* @param label - Label name
|
|
73
|
+
* @returns Array of label values
|
|
74
|
+
*/
|
|
75
|
+
labelValues(label: string): Promise<string[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Get metric metadata from Prometheus
|
|
78
|
+
*
|
|
79
|
+
* @returns Map of metric name to metadata array
|
|
80
|
+
*/
|
|
81
|
+
metadata(): Promise<Record<string, MetadataEntry[]>>;
|
|
82
|
+
/**
|
|
83
|
+
* Get all series matching a set of label matchers
|
|
84
|
+
*
|
|
85
|
+
* @param match - Label matcher expressions
|
|
86
|
+
* @param start - Optional start time
|
|
87
|
+
* @param end - Optional end time
|
|
88
|
+
* @returns Array of label sets
|
|
89
|
+
*/
|
|
90
|
+
series(match: string[], start?: Date, end?: Date): Promise<Record<string, string>[]>;
|
|
91
|
+
/**
|
|
92
|
+
* Check if Prometheus is reachable
|
|
93
|
+
*/
|
|
94
|
+
isHealthy(): Promise<boolean>;
|
|
95
|
+
/**
|
|
96
|
+
* List all available metrics from the live Prometheus cluster.
|
|
97
|
+
*
|
|
98
|
+
* Returns raw metric metadata. For semantic search (e.g., "memory usage"),
|
|
99
|
+
* use MetricSearchEngine instead.
|
|
100
|
+
*
|
|
101
|
+
* @returns Array of all available metrics with name, type, and description
|
|
102
|
+
*/
|
|
103
|
+
listMetrics(): Promise<MetricInfo[]>;
|
|
104
|
+
/**
|
|
105
|
+
* Parse time series from prometheus-query result
|
|
106
|
+
*/
|
|
107
|
+
private parseTimeSeries;
|
|
108
|
+
/**
|
|
109
|
+
* Parse sample values
|
|
110
|
+
*/
|
|
111
|
+
private parseSamples;
|
|
112
|
+
}
|
|
113
|
+
interface MetadataEntry {
|
|
114
|
+
type?: string;
|
|
115
|
+
help?: string;
|
|
116
|
+
unit?: string;
|
|
117
|
+
}
|
|
118
|
+
export {};
|
|
119
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,uBAAuB,EACvB,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAGhB,UAAU,EACX,MAAM,YAAY,CAAC;AAKpB;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,MAAM,CAA6B;gBAE/B,OAAO,EAAE,uBAAuB;IAO5C;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;YACW,SAAS;IAcvB;;;;;;;;;;;;;;;OAeG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAUvE;;;;;;;;;;;;;;;;;;;OAmBG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAa/E;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAKrC;;;;;OAKG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKnD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAK1D;;;;;;;OAOG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,CAAC,EAAE,IAAI,EACZ,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAKpC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAWnC;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAgB1C;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,YAAY;CAMrB;AAiBD,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrometheusClient - Typed wrapper around prometheus-query library
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: This client executes PromQL queries. To DISCOVER available metrics,
|
|
5
|
+
* use MetricSearchEngine.search() first.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Typed client for executing PromQL queries against Prometheus.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: This client runs PromQL expressions. To discover available metrics,
|
|
11
|
+
* use MetricSearchEngine.search() - it provides semantic search over metric
|
|
12
|
+
* names and descriptions.
|
|
13
|
+
*/
|
|
14
|
+
export class PrometheusClient {
|
|
15
|
+
options;
|
|
16
|
+
driver = null;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.options = {
|
|
19
|
+
timeout: 30000,
|
|
20
|
+
...options,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the Prometheus endpoint URL
|
|
25
|
+
*/
|
|
26
|
+
getEndpoint() {
|
|
27
|
+
return this.options.endpoint;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the Prometheus driver
|
|
31
|
+
*/
|
|
32
|
+
async getDriver() {
|
|
33
|
+
if (this.driver) {
|
|
34
|
+
return this.driver;
|
|
35
|
+
}
|
|
36
|
+
const { PrometheusDriver } = await import('prometheus-query');
|
|
37
|
+
this.driver = new PrometheusDriver({
|
|
38
|
+
endpoint: this.options.endpoint,
|
|
39
|
+
timeout: this.options.timeout,
|
|
40
|
+
});
|
|
41
|
+
return this.driver;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Execute an instant PromQL query.
|
|
45
|
+
*
|
|
46
|
+
* This runs a PromQL expression and returns the current value.
|
|
47
|
+
* You must already know the metric name - use MetricSearchEngine.search()
|
|
48
|
+
* to discover available metrics first.
|
|
49
|
+
*
|
|
50
|
+
* @param promql - PromQL expression (e.g., "node_memory_MemTotal_bytes")
|
|
51
|
+
* @param time - Optional evaluation time (defaults to now)
|
|
52
|
+
* @returns Query result with time series data
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // First discover metrics with MetricSearchEngine.search("memory")
|
|
56
|
+
* // Then execute with known metric name:
|
|
57
|
+
* const result = await client.execute("node_memory_MemTotal_bytes");
|
|
58
|
+
*/
|
|
59
|
+
async execute(promql, time) {
|
|
60
|
+
const driver = await this.getDriver();
|
|
61
|
+
const result = await driver.instantQuery(promql, time);
|
|
62
|
+
return {
|
|
63
|
+
resultType: result.resultType,
|
|
64
|
+
data: this.parseTimeSeries(result.result),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Execute a range PromQL query over a time period.
|
|
69
|
+
*
|
|
70
|
+
* This runs a PromQL expression over a time range and returns samples.
|
|
71
|
+
* You must already know the metric name - use MetricSearchEngine.search()
|
|
72
|
+
* to discover available metrics first.
|
|
73
|
+
*
|
|
74
|
+
* @param promql - PromQL expression (e.g., "rate(http_requests_total[5m])")
|
|
75
|
+
* @param range - Time range with start, end, and step
|
|
76
|
+
* @returns Query result with time series data
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* // First discover metrics with MetricSearchEngine.search("memory")
|
|
80
|
+
* // Then execute with known metric name:
|
|
81
|
+
* const result = await client.executeRange("node_memory_MemTotal_bytes", {
|
|
82
|
+
* start: new Date(Date.now() - 3600000),
|
|
83
|
+
* end: new Date(),
|
|
84
|
+
* step: "5m"
|
|
85
|
+
* });
|
|
86
|
+
*/
|
|
87
|
+
async executeRange(promql, range) {
|
|
88
|
+
const driver = await this.getDriver();
|
|
89
|
+
const start = range.start instanceof Date ? range.start : new Date(range.start * 1000);
|
|
90
|
+
const end = range.end instanceof Date ? range.end : new Date(range.end * 1000);
|
|
91
|
+
const result = await driver.rangeQuery(promql, start, end, range.step);
|
|
92
|
+
return {
|
|
93
|
+
resultType: 'matrix',
|
|
94
|
+
data: this.parseTimeSeries(result.result),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get all label names
|
|
99
|
+
*/
|
|
100
|
+
async labelNames() {
|
|
101
|
+
const driver = await this.getDriver();
|
|
102
|
+
return driver.labelNames();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get all values for a label
|
|
106
|
+
*
|
|
107
|
+
* @param label - Label name
|
|
108
|
+
* @returns Array of label values
|
|
109
|
+
*/
|
|
110
|
+
async labelValues(label) {
|
|
111
|
+
const driver = await this.getDriver();
|
|
112
|
+
return driver.labelValues(label);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get metric metadata from Prometheus
|
|
116
|
+
*
|
|
117
|
+
* @returns Map of metric name to metadata array
|
|
118
|
+
*/
|
|
119
|
+
async metadata() {
|
|
120
|
+
const driver = await this.getDriver();
|
|
121
|
+
return driver.metadata();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get all series matching a set of label matchers
|
|
125
|
+
*
|
|
126
|
+
* @param match - Label matcher expressions
|
|
127
|
+
* @param start - Optional start time
|
|
128
|
+
* @param end - Optional end time
|
|
129
|
+
* @returns Array of label sets
|
|
130
|
+
*/
|
|
131
|
+
async series(match, start, end) {
|
|
132
|
+
const driver = await this.getDriver();
|
|
133
|
+
return driver.series(match, start, end);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Check if Prometheus is reachable
|
|
137
|
+
*/
|
|
138
|
+
async isHealthy() {
|
|
139
|
+
try {
|
|
140
|
+
const driver = await this.getDriver();
|
|
141
|
+
// Try to get label names as a health check
|
|
142
|
+
await driver.labelNames();
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* List all available metrics from the live Prometheus cluster.
|
|
151
|
+
*
|
|
152
|
+
* Returns raw metric metadata. For semantic search (e.g., "memory usage"),
|
|
153
|
+
* use MetricSearchEngine instead.
|
|
154
|
+
*
|
|
155
|
+
* @returns Array of all available metrics with name, type, and description
|
|
156
|
+
*/
|
|
157
|
+
async listMetrics() {
|
|
158
|
+
const allMetadata = await this.metadata();
|
|
159
|
+
const metrics = [];
|
|
160
|
+
for (const [name, entries] of Object.entries(allMetadata)) {
|
|
161
|
+
const entry = Array.isArray(entries) ? entries[0] : entries;
|
|
162
|
+
metrics.push({
|
|
163
|
+
name,
|
|
164
|
+
type: entry?.type || 'unknown',
|
|
165
|
+
help: entry?.help || 'No description available',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return metrics;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Parse time series from prometheus-query result
|
|
172
|
+
*/
|
|
173
|
+
parseTimeSeries(result) {
|
|
174
|
+
return result.map((series) => ({
|
|
175
|
+
labels: series.metric.labels || {},
|
|
176
|
+
samples: this.parseSamples(series.values || (series.value ? [series.value] : [])),
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Parse sample values
|
|
181
|
+
*/
|
|
182
|
+
parseSamples(values) {
|
|
183
|
+
return values.filter((v) => v !== undefined).map((v) => ({
|
|
184
|
+
time: typeof v.time === 'number' ? v.time : v.time.getTime() / 1000,
|
|
185
|
+
value: typeof v.value === 'string' ? parseFloat(v.value) : v.value,
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @prodisco/prometheus-client
|
|
3
|
+
*
|
|
4
|
+
* Typed Prometheus client with semantic metric discovery for AI agents
|
|
5
|
+
*/
|
|
6
|
+
export { PrometheusClient } from './client.js';
|
|
7
|
+
export { MetricSearchEngine, createMetricSearchEngine, type MetricSearchOptions, } from './metrics.js';
|
|
8
|
+
export type { MetricType, MetricInfo, MetricMetadata, PrometheusClientOptions, TimeRange, Sample, TimeSeries, InstantQueryResult, RangeQueryResult, } from './types.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,uBAAuB,EACvB,SAAS,EACT,MAAM,EACN,UAAU,EACV,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @prodisco/prometheus-client
|
|
3
|
+
*
|
|
4
|
+
* Typed Prometheus client with semantic metric discovery for AI agents
|
|
5
|
+
*/
|
|
6
|
+
// Client
|
|
7
|
+
export { PrometheusClient } from './client.js';
|
|
8
|
+
// Metric search
|
|
9
|
+
export { MetricSearchEngine, createMetricSearchEngine, } from './metrics.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,SAAS;AACT,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,gBAAgB;AAChB,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GAEzB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metric search engine using Orama for semantic search
|
|
3
|
+
*
|
|
4
|
+
* Indexes live Prometheus metrics and enables semantic search
|
|
5
|
+
* by name and description, not just regex pattern matching.
|
|
6
|
+
*/
|
|
7
|
+
import type { MetricInfo, MetricType } from './types.js';
|
|
8
|
+
import { PrometheusClient } from './client.js';
|
|
9
|
+
/**
|
|
10
|
+
* Search options for finding metrics
|
|
11
|
+
*/
|
|
12
|
+
export interface MetricSearchOptions {
|
|
13
|
+
/** Maximum number of results (default: 20) */
|
|
14
|
+
limit?: number;
|
|
15
|
+
/** Filter by metric type */
|
|
16
|
+
type?: MetricType;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* MetricSearchEngine - Semantic search for Prometheus metrics
|
|
20
|
+
*
|
|
21
|
+
* Uses Orama search engine to index metric names and descriptions,
|
|
22
|
+
* enabling natural language search like "memory consumption" instead
|
|
23
|
+
* of requiring exact metric names.
|
|
24
|
+
*/
|
|
25
|
+
export declare class MetricSearchEngine {
|
|
26
|
+
private client;
|
|
27
|
+
private searchEngine;
|
|
28
|
+
private indexed;
|
|
29
|
+
private indexedCount;
|
|
30
|
+
private lastIndexTime;
|
|
31
|
+
/** Cache TTL in milliseconds (5 minutes) */
|
|
32
|
+
private static readonly CACHE_TTL_MS;
|
|
33
|
+
constructor(client: PrometheusClient);
|
|
34
|
+
/**
|
|
35
|
+
* Index all metrics from Prometheus into the search engine.
|
|
36
|
+
*
|
|
37
|
+
* @param force - Force re-indexing even if cache is valid
|
|
38
|
+
*/
|
|
39
|
+
index(force?: boolean): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Search for metrics using natural language.
|
|
42
|
+
*
|
|
43
|
+
* Examples:
|
|
44
|
+
* - "memory usage" → finds container_memory_usage_bytes, etc.
|
|
45
|
+
* - "http requests" → finds http_requests_total, etc.
|
|
46
|
+
* - "cpu" → finds all CPU-related metrics
|
|
47
|
+
*
|
|
48
|
+
* @param query - Natural language search query
|
|
49
|
+
* @param options - Search options (limit, type filter)
|
|
50
|
+
* @returns Ranked list of matching metrics
|
|
51
|
+
*/
|
|
52
|
+
search(query: string, options?: MetricSearchOptions): Promise<MetricInfo[]>;
|
|
53
|
+
/**
|
|
54
|
+
* List all indexed metrics
|
|
55
|
+
*/
|
|
56
|
+
list(options?: MetricSearchOptions): Promise<MetricInfo[]>;
|
|
57
|
+
getIndexedCount(): number;
|
|
58
|
+
isReady(): boolean;
|
|
59
|
+
clear(): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create a MetricSearchEngine from a Prometheus endpoint
|
|
63
|
+
*/
|
|
64
|
+
export declare function createMetricSearchEngine(endpoint: string): MetricSearchEngine;
|
|
65
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,4BAA4B;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,aAAa,CAAuB;IAE5C,4CAA4C;IAC5C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAiB;gBAEzC,MAAM,EAAE,gBAAgB;IAUpC;;;;OAIG;IACG,KAAK,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAoD3C;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAoBrF;;OAEG;IACG,IAAI,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAoBpE,eAAe,IAAI,MAAM;IAIzB,OAAO,IAAI,OAAO;IAIZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAM7B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAG7E"}
|
package/dist/metrics.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metric search engine using Orama for semantic search
|
|
3
|
+
*
|
|
4
|
+
* Indexes live Prometheus metrics and enables semantic search
|
|
5
|
+
* by name and description, not just regex pattern matching.
|
|
6
|
+
*/
|
|
7
|
+
import { SearchEngine } from '@prodisco/search-libs';
|
|
8
|
+
import { PrometheusClient } from './client.js';
|
|
9
|
+
/**
|
|
10
|
+
* MetricSearchEngine - Semantic search for Prometheus metrics
|
|
11
|
+
*
|
|
12
|
+
* Uses Orama search engine to index metric names and descriptions,
|
|
13
|
+
* enabling natural language search like "memory consumption" instead
|
|
14
|
+
* of requiring exact metric names.
|
|
15
|
+
*/
|
|
16
|
+
export class MetricSearchEngine {
|
|
17
|
+
client;
|
|
18
|
+
searchEngine;
|
|
19
|
+
indexed = false;
|
|
20
|
+
indexedCount = 0;
|
|
21
|
+
lastIndexTime = null;
|
|
22
|
+
/** Cache TTL in milliseconds (5 minutes) */
|
|
23
|
+
static CACHE_TTL_MS = 5 * 60 * 1000;
|
|
24
|
+
constructor(client) {
|
|
25
|
+
this.client = client;
|
|
26
|
+
this.searchEngine = new SearchEngine({
|
|
27
|
+
tokenizerOptions: {
|
|
28
|
+
stemming: true,
|
|
29
|
+
stemmerSkipProperties: ['name'],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Index all metrics from Prometheus into the search engine.
|
|
35
|
+
*
|
|
36
|
+
* @param force - Force re-indexing even if cache is valid
|
|
37
|
+
*/
|
|
38
|
+
async index(force = false) {
|
|
39
|
+
// Check if cache is still valid
|
|
40
|
+
if (!force && this.indexed && this.lastIndexTime) {
|
|
41
|
+
const elapsed = Date.now() - this.lastIndexTime;
|
|
42
|
+
if (elapsed < MetricSearchEngine.CACHE_TTL_MS) {
|
|
43
|
+
return this.indexedCount;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Fetch all metrics from Prometheus
|
|
47
|
+
const metrics = await this.client.listMetrics();
|
|
48
|
+
// Build documents for indexing
|
|
49
|
+
const docs = metrics.map((m) => ({
|
|
50
|
+
id: `metric:${m.name}`,
|
|
51
|
+
documentType: 'metric',
|
|
52
|
+
name: m.name,
|
|
53
|
+
description: m.help,
|
|
54
|
+
searchTokens: `${m.name.replace(/_/g, ' ')} ${m.type} ${m.help}`,
|
|
55
|
+
library: 'prometheus',
|
|
56
|
+
category: m.type,
|
|
57
|
+
properties: '',
|
|
58
|
+
typeDefinition: '',
|
|
59
|
+
nestedTypes: '',
|
|
60
|
+
typeKind: '',
|
|
61
|
+
parameters: '',
|
|
62
|
+
returnType: '',
|
|
63
|
+
returnTypeDefinition: '',
|
|
64
|
+
signature: '',
|
|
65
|
+
className: '',
|
|
66
|
+
filePath: '',
|
|
67
|
+
keywords: m.type,
|
|
68
|
+
}));
|
|
69
|
+
// Re-initialize search engine for fresh index
|
|
70
|
+
this.searchEngine = new SearchEngine({
|
|
71
|
+
tokenizerOptions: {
|
|
72
|
+
stemming: true,
|
|
73
|
+
stemmerSkipProperties: ['name'],
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
await this.searchEngine.initialize();
|
|
77
|
+
await this.searchEngine.insertBatch(docs);
|
|
78
|
+
this.indexed = true;
|
|
79
|
+
this.indexedCount = docs.length;
|
|
80
|
+
this.lastIndexTime = Date.now();
|
|
81
|
+
return this.indexedCount;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Search for metrics using natural language.
|
|
85
|
+
*
|
|
86
|
+
* Examples:
|
|
87
|
+
* - "memory usage" → finds container_memory_usage_bytes, etc.
|
|
88
|
+
* - "http requests" → finds http_requests_total, etc.
|
|
89
|
+
* - "cpu" → finds all CPU-related metrics
|
|
90
|
+
*
|
|
91
|
+
* @param query - Natural language search query
|
|
92
|
+
* @param options - Search options (limit, type filter)
|
|
93
|
+
* @returns Ranked list of matching metrics
|
|
94
|
+
*/
|
|
95
|
+
async search(query, options = {}) {
|
|
96
|
+
const { limit = 20, type } = options;
|
|
97
|
+
if (!this.indexed) {
|
|
98
|
+
await this.index();
|
|
99
|
+
}
|
|
100
|
+
const result = await this.searchEngine.search({
|
|
101
|
+
query,
|
|
102
|
+
limit,
|
|
103
|
+
category: type,
|
|
104
|
+
});
|
|
105
|
+
return result.results.map((doc) => ({
|
|
106
|
+
name: doc.name,
|
|
107
|
+
type: doc.category || 'unknown',
|
|
108
|
+
help: doc.description,
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* List all indexed metrics
|
|
113
|
+
*/
|
|
114
|
+
async list(options = {}) {
|
|
115
|
+
const { limit = 100, type } = options;
|
|
116
|
+
if (!this.indexed) {
|
|
117
|
+
await this.index();
|
|
118
|
+
}
|
|
119
|
+
const result = await this.searchEngine.search({
|
|
120
|
+
query: '',
|
|
121
|
+
limit,
|
|
122
|
+
category: type,
|
|
123
|
+
});
|
|
124
|
+
return result.results.map((doc) => ({
|
|
125
|
+
name: doc.name,
|
|
126
|
+
type: doc.category || 'unknown',
|
|
127
|
+
help: doc.description,
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
getIndexedCount() {
|
|
131
|
+
return this.indexedCount;
|
|
132
|
+
}
|
|
133
|
+
isReady() {
|
|
134
|
+
return this.indexed;
|
|
135
|
+
}
|
|
136
|
+
async clear() {
|
|
137
|
+
await this.searchEngine.shutdown();
|
|
138
|
+
this.indexed = false;
|
|
139
|
+
this.indexedCount = 0;
|
|
140
|
+
this.lastIndexTime = null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create a MetricSearchEngine from a Prometheus endpoint
|
|
145
|
+
*/
|
|
146
|
+
export function createMetricSearchEngine(endpoint) {
|
|
147
|
+
const client = new PrometheusClient({ endpoint });
|
|
148
|
+
return new MetricSearchEngine(client);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for Prometheus client
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Metric type as reported by Prometheus
|
|
6
|
+
*/
|
|
7
|
+
export type MetricType = 'counter' | 'gauge' | 'histogram' | 'summary' | 'unknown';
|
|
8
|
+
/**
|
|
9
|
+
* Information about a Prometheus metric
|
|
10
|
+
*/
|
|
11
|
+
export interface MetricInfo {
|
|
12
|
+
/** Metric name (e.g., "http_requests_total") */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Metric type (counter, gauge, histogram, summary) */
|
|
15
|
+
type: MetricType;
|
|
16
|
+
/** Help text / description */
|
|
17
|
+
help: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Metadata for a metric as returned by Prometheus API
|
|
21
|
+
*/
|
|
22
|
+
export interface MetricMetadata {
|
|
23
|
+
type?: string;
|
|
24
|
+
help?: string;
|
|
25
|
+
unit?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Options for creating PrometheusClient
|
|
29
|
+
*/
|
|
30
|
+
export interface PrometheusClientOptions {
|
|
31
|
+
/** Prometheus server endpoint (e.g., "http://prometheus:9090") */
|
|
32
|
+
endpoint: string;
|
|
33
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
34
|
+
timeout?: number;
|
|
35
|
+
/** Custom headers for requests */
|
|
36
|
+
headers?: Record<string, string>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Time range for range queries
|
|
40
|
+
*/
|
|
41
|
+
export interface TimeRange {
|
|
42
|
+
/** Start time (Date or Unix timestamp in seconds) */
|
|
43
|
+
start: Date | number;
|
|
44
|
+
/** End time (Date or Unix timestamp in seconds) */
|
|
45
|
+
end: Date | number;
|
|
46
|
+
/** Step interval (e.g., "15s", "1m", "5m") */
|
|
47
|
+
step: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A single sample point in a time series
|
|
51
|
+
*/
|
|
52
|
+
export interface Sample {
|
|
53
|
+
/** Unix timestamp in seconds */
|
|
54
|
+
time: number;
|
|
55
|
+
/** Metric value */
|
|
56
|
+
value: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A time series with labels and samples
|
|
60
|
+
*/
|
|
61
|
+
export interface TimeSeries {
|
|
62
|
+
/** Metric labels */
|
|
63
|
+
labels: Record<string, string>;
|
|
64
|
+
/** Sample values */
|
|
65
|
+
samples: Sample[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Result of an instant query
|
|
69
|
+
*/
|
|
70
|
+
export interface InstantQueryResult {
|
|
71
|
+
/** Result type (vector, matrix, scalar, string) */
|
|
72
|
+
resultType: 'vector' | 'matrix' | 'scalar' | 'string';
|
|
73
|
+
/** Time series data */
|
|
74
|
+
data: TimeSeries[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Result of a range query
|
|
78
|
+
*/
|
|
79
|
+
export interface RangeQueryResult {
|
|
80
|
+
/** Result type (always matrix for range queries) */
|
|
81
|
+
resultType: 'matrix';
|
|
82
|
+
/** Time series data with multiple samples */
|
|
83
|
+
data: TimeSeries[];
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IAEb,uDAAuD;IACvD,IAAI,EAAE,UAAU,CAAC;IAEjB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IAEjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,qDAAqD;IACrD,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;IAErB,mDAAmD;IACnD,GAAG,EAAE,IAAI,GAAG,MAAM,CAAC;IAEnB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IAEb,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/B,oBAAoB;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAEtD,uBAAuB;IACvB,IAAI,EAAE,UAAU,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,UAAU,EAAE,QAAQ,CAAC;IAErB,6CAA6C;IAC7C,IAAI,EAAE,UAAU,EAAE,CAAC;CACpB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prodisco/prometheus-client",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Typed Prometheus client with metric discovery for AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"clean": "rm -rf dist",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
19
|
+
"typecheck": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"prometheus",
|
|
23
|
+
"metrics",
|
|
24
|
+
"monitoring",
|
|
25
|
+
"typescript",
|
|
26
|
+
"ai-agents"
|
|
27
|
+
],
|
|
28
|
+
"author": "",
|
|
29
|
+
"license": "ISC",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@prodisco/search-libs": "*",
|
|
32
|
+
"prometheus-query": "^3.4.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^24.10.1",
|
|
36
|
+
"typescript": "^5.9.3",
|
|
37
|
+
"vitest": "^4.0.15"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"README.md"
|
|
42
|
+
]
|
|
43
|
+
}
|