@gravitee/gamma-lib-observability 1.29.0 → 1.30.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/INTEGRATION.md +45 -55
- package/QUERYING.md +5 -5
- package/USAGE_GUIDE.md +178 -231
- package/dist/build-observability-base-url.d.ts +12 -12
- package/dist/build-observability-base-url.d.ts.map +1 -1
- package/dist/build-traces-base-url.d.ts +9 -18
- package/dist/build-traces-base-url.d.ts.map +1 -1
- package/dist/data-sources/http-data-source.d.ts.map +1 -1
- package/dist/data-sources/http-filter-source.d.ts.map +1 -1
- package/dist/data-sources/http-logs-source.d.ts +1 -13
- package/dist/data-sources/http-logs-source.d.ts.map +1 -1
- package/dist/data-sources/logs-data-source.d.ts +1 -1
- package/dist/data-sources/logs-data-source.d.ts.map +1 -1
- package/dist/filters/filter-provider.d.ts +6 -0
- package/dist/filters/filter-provider.d.ts.map +1 -1
- package/dist/hooks/query-keys.d.ts +1 -1
- package/dist/hooks/query-keys.d.ts.map +1 -1
- package/dist/hooks/use-log-detail-query.d.ts +1 -0
- package/dist/hooks/use-log-detail-query.d.ts.map +1 -1
- package/dist/hooks/use-logs-histogram-query.d.ts +0 -7
- package/dist/hooks/use-logs-histogram-query.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1460 -1498
- package/dist/logs/LogsExplorerPage.d.ts +1 -7
- package/dist/logs/LogsExplorerPage.d.ts.map +1 -1
- package/dist/logs/detail/components/LogDetailContent.d.ts.map +1 -1
- package/dist/logs/detail/components/LogDetailContextChart.d.ts +1 -3
- package/dist/logs/detail/components/LogDetailContextChart.d.ts.map +1 -1
- package/dist/logs/detail/components/LogDetailDrawer.d.ts +2 -1
- package/dist/logs/detail/components/LogDetailDrawer.d.ts.map +1 -1
- package/dist/logs/detail/components/LogDetailPage.d.ts.map +1 -1
- package/dist/logs/detail/types.d.ts +0 -7
- package/dist/logs/detail/types.d.ts.map +1 -1
- package/dist/logs/index.d.ts +0 -2
- package/dist/logs/index.d.ts.map +1 -1
- package/dist/routing/LogsRouteElement.d.ts +3 -3
- package/dist/routing/LogsRouteElement.d.ts.map +1 -1
- package/dist/routing/ObservabilityRoutes.d.ts +2 -1
- package/dist/routing/ObservabilityRoutes.d.ts.map +1 -1
- package/dist/routing/types.d.ts +47 -16
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/styles/observability.css +1 -1
- package/package.json +5 -5
- package/dist/logs/analytics-filter-mapping.d.ts +0 -35
- package/dist/logs/analytics-filter-mapping.d.ts.map +0 -1
package/USAGE_GUIDE.md
CHANGED
|
@@ -8,8 +8,8 @@ Your module must provide:
|
|
|
8
8
|
- `react-dom` ^19.0.0
|
|
9
9
|
- `react-router-dom` ^7.0.0
|
|
10
10
|
- `@tanstack/react-query` ^5.0.0
|
|
11
|
-
- `@gravitee/graphene-core` ^2.
|
|
12
|
-
- `@gravitee/graphene-charts` ^2.
|
|
11
|
+
- `@gravitee/graphene-core` ^2.49.0
|
|
12
|
+
- `@gravitee/graphene-charts` ^2.49.0
|
|
13
13
|
|
|
14
14
|
> **Important:** Your module root must wrap with `<QueryClientProvider>`. The lib does not instantiate its own `QueryClient`.
|
|
15
15
|
|
|
@@ -21,150 +21,99 @@ yarn add @gravitee/gamma-lib-observability
|
|
|
21
21
|
|
|
22
22
|
## Quick start
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Three steps to get a working observability section in your module. The library handles data fetching, filter state, URL persistence, and page rendering internally — no manual provider wiring or custom data sources needed.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
28
|
-
import {
|
|
29
|
-
CapabilityProvider,
|
|
30
|
-
MetricsDataSourceProvider,
|
|
31
|
-
LogsDataSourceProvider,
|
|
32
|
-
TracesDataSourceProvider,
|
|
33
|
-
DashboardPersistenceProvider,
|
|
34
|
-
} from '@gravitee/gamma-lib-observability';
|
|
26
|
+
### 1. Define features
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
Declare which observability features your module enables and scope them to your API types via `scopeApiTypes`:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { defineObservabilityFeatures } from '@gravitee/gamma-lib-observability';
|
|
32
|
+
import { myDashboardTemplates } from './templates';
|
|
33
|
+
|
|
34
|
+
export const observability = defineObservabilityFeatures({
|
|
35
|
+
scopeApiTypes: ['MCP', 'LLM'],
|
|
36
|
+
features: {
|
|
37
|
+
dashboards: { enabled: true, templates: myDashboardTemplates },
|
|
38
|
+
logs: { enabled: true },
|
|
39
|
+
tracing: { enabled: true },
|
|
40
|
+
},
|
|
41
|
+
nav: { label: 'Observability' },
|
|
38
42
|
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`scopeApiTypes` generates `API_TYPE` context filters and scoped filter providers for all features. Override per-feature when needed (e.g. logs scoped to `['MCP']` only while dashboards sees `['MCP', 'LLM']`).
|
|
46
|
+
|
|
47
|
+
### 2. Mount routes
|
|
48
|
+
|
|
49
|
+
Mount `<observability.Routes>` under your module's route tree. Pass `baseUrl` (built from the Gamma API origin) and `http` for authentication. The library auto-creates all HTTP data sources, filter providers, pages, and log columns internally.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { buildObservabilityBaseUrl } from '@gravitee/gamma-lib-observability';
|
|
53
|
+
import { observability } from './config/observability';
|
|
54
|
+
|
|
55
|
+
function AppRoutes() {
|
|
56
|
+
const baseUrl = buildObservabilityBaseUrl(gammaBaseURL, organizationId, environmentId);
|
|
39
57
|
|
|
40
|
-
function App() {
|
|
41
58
|
return (
|
|
42
|
-
<
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</CapabilityProvider>
|
|
54
|
-
</QueryClientProvider>
|
|
59
|
+
<Routes>
|
|
60
|
+
<Route
|
|
61
|
+
path="observe/*"
|
|
62
|
+
element={
|
|
63
|
+
<observability.Routes
|
|
64
|
+
baseUrl={baseUrl}
|
|
65
|
+
http={{ credentials: 'include', headers: () => ({ 'X-Xsrf-Token': readXsrfToken() }) }}
|
|
66
|
+
/>
|
|
67
|
+
}
|
|
68
|
+
/>
|
|
69
|
+
</Routes>
|
|
55
70
|
);
|
|
56
71
|
}
|
|
57
72
|
```
|
|
58
73
|
|
|
59
|
-
|
|
74
|
+
Log columns default to `buildDefaultConnectionLogColumns`, and row identity defaults to `row.requestId` / `row.apiId`. Override via `logsColumns`, `logsGetRowId`, `logsGetApiId` for custom row types (see [Advanced: Custom data sources](#advanced-custom-data-sources)).
|
|
60
75
|
|
|
61
|
-
|
|
62
|
-
import type { DashboardCapabilities } from '@gravitee/gamma-lib-observability';
|
|
76
|
+
### 3. Register navigation
|
|
63
77
|
|
|
64
|
-
|
|
65
|
-
'observability.dashboards.read': true,
|
|
66
|
-
'observability.dashboards.write': false,
|
|
67
|
-
'observability.logs.read': true,
|
|
68
|
-
'observability.traces.read': false,
|
|
69
|
-
};
|
|
70
|
-
```
|
|
78
|
+
Add the lib's nav group to your module's sidenav. Only enabled features appear as items.
|
|
71
79
|
|
|
72
|
-
|
|
80
|
+
```ts
|
|
81
|
+
const NAV_GROUPS = [...existingGroups, observability.navGroup];
|
|
82
|
+
```
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
That's it — you now have dashboards, logs, and tracing with scoped filters, URL-persisted state, and authenticated HTTP requests. See the sections below for customization options.
|
|
75
85
|
|
|
76
|
-
|
|
86
|
+
## Testing
|
|
77
87
|
|
|
78
|
-
|
|
88
|
+
The lib exports a testing helper from the `./testing` subpath:
|
|
79
89
|
|
|
80
|
-
```
|
|
81
|
-
import
|
|
90
|
+
```tsx
|
|
91
|
+
import { renderWithObservability } from '@gravitee/gamma-lib-observability/testing';
|
|
82
92
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return response.json();
|
|
88
|
-
},
|
|
89
|
-
async fetchFacets(request) {
|
|
90
|
-
const { field, timeRange, signal } = request;
|
|
91
|
-
const response = await fetch(`/api/metrics/facets?field=${field}`, { signal });
|
|
92
|
-
return response.json();
|
|
93
|
-
},
|
|
94
|
-
async fetchMeasures(request) {
|
|
95
|
-
const { metrics, timeRange, signal } = request;
|
|
96
|
-
const response = await fetch(`/api/metrics/measures`, {
|
|
97
|
-
method: 'POST',
|
|
98
|
-
body: JSON.stringify({ metrics }),
|
|
99
|
-
signal,
|
|
100
|
-
});
|
|
101
|
-
return response.json();
|
|
102
|
-
},
|
|
93
|
+
const mockMetrics: MetricsDataSource = {
|
|
94
|
+
fetchTimeSeries: vi.fn().mockResolvedValue([]),
|
|
95
|
+
fetchFacets: vi.fn().mockResolvedValue([]),
|
|
96
|
+
fetchMeasures: vi.fn().mockResolvedValue([]),
|
|
103
97
|
};
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
#### Logs (generic — each module defines its own row type)
|
|
107
98
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
method: string;
|
|
116
|
-
status: number;
|
|
117
|
-
uri: string;
|
|
118
|
-
apiId: string;
|
|
119
|
-
apiName: string;
|
|
120
|
-
responseTime: number;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// 2. Implement the typed data source
|
|
124
|
-
export const httpLogsDataSource: LogsDataSource<HttpProxyLog> = {
|
|
125
|
-
async fetchLogs(query) {
|
|
126
|
-
const response = await fetch('/api/logs', {
|
|
127
|
-
method: 'POST',
|
|
128
|
-
body: JSON.stringify({
|
|
129
|
-
timeRange: query.timeRange,
|
|
130
|
-
filters: query.filters,
|
|
131
|
-
search: query.search,
|
|
132
|
-
page: query.page,
|
|
133
|
-
perPage: query.perPage,
|
|
134
|
-
}),
|
|
135
|
-
signal: query.signal,
|
|
136
|
-
});
|
|
137
|
-
const json = await response.json();
|
|
138
|
-
return {
|
|
139
|
-
entries: json.data as HttpProxyLog[],
|
|
140
|
-
totalCount: json.total,
|
|
141
|
-
page: json.page,
|
|
142
|
-
pageCount: json.pageCount,
|
|
143
|
-
};
|
|
99
|
+
const { getByText } = renderWithObservability(<MyComponent />, {
|
|
100
|
+
dataSources: { metrics: mockMetrics },
|
|
101
|
+
capabilities: {
|
|
102
|
+
'observability.dashboards.read': true,
|
|
103
|
+
'observability.dashboards.write': false,
|
|
104
|
+
'observability.logs.read': true,
|
|
105
|
+
'observability.traces.read': false,
|
|
144
106
|
},
|
|
145
|
-
};
|
|
107
|
+
});
|
|
146
108
|
```
|
|
147
109
|
|
|
148
|
-
|
|
110
|
+
The helper wraps the component with `QueryClientProvider`, `CapabilityProvider`, and all DataSource providers you pass.
|
|
111
|
+
|
|
112
|
+
---
|
|
149
113
|
|
|
150
|
-
|
|
151
|
-
import { useTimeSeriesQuery, useMeasuresQuery } from '@gravitee/gamma-lib-observability';
|
|
152
|
-
|
|
153
|
-
function RequestRateChart() {
|
|
154
|
-
const { data, isLoading, error } = useTimeSeriesQuery({
|
|
155
|
-
metrics: [{ name: 'HTTP_REQUESTS', measures: ['COUNT'] }],
|
|
156
|
-
timeRange: { type: 'relative', period: '1h' },
|
|
157
|
-
interval: 60_000,
|
|
158
|
-
by: ['HTTP_STATUS_CODE_GROUP'],
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
if (isLoading) return <Spinner />;
|
|
162
|
-
if (error) return <ErrorBanner error={error} />;
|
|
163
|
-
return <LineChart data={data} />;
|
|
164
|
-
}
|
|
165
|
-
```
|
|
114
|
+
## Hooks reference
|
|
166
115
|
|
|
167
|
-
|
|
116
|
+
The library exposes TanStack Query hooks for direct data fetching. In most cases you do not need these — the auto-mounted pages handle data fetching internally. Use them when building custom pages or embedding widgets outside the `observe/*` routes.
|
|
168
117
|
|
|
169
118
|
| Hook | DataSource | Returns |
|
|
170
119
|
| ------------------------- | ---------------------- | ------------------------------- |
|
|
@@ -174,10 +123,6 @@ Hooks available:
|
|
|
174
123
|
| `useLogsQuery<TRow>` | `LogsDataSource<TRow>` | `LogsQueryResult<TRow>` |
|
|
175
124
|
| `useLogsPagedQuery<TRow>` | `LogsDataSource<TRow>` | `UseLogsPagedQueryResult<TRow>` |
|
|
176
125
|
|
|
177
|
-
> For the full analytics request capability (measures / facets / time-series fields, `by`, `sorts`,
|
|
178
|
-
> `ranges`, per-metric filters, defaults, and the widget → request mapping), see
|
|
179
|
-
> [`QUERYING.md`](./QUERYING.md).
|
|
180
|
-
|
|
181
126
|
All hooks:
|
|
182
127
|
|
|
183
128
|
- Use `observabilityQueryKeys` for cache key derivation
|
|
@@ -185,57 +130,107 @@ All hooks:
|
|
|
185
130
|
- Default `staleTime: 30_000`. `refetchOnWindowFocus` is **not** set by the library — your host `QueryClient` defaults apply (set it there if you want refetch-on-focus)
|
|
186
131
|
- Accept an `enabled` param and additional TanStack Query options
|
|
187
132
|
|
|
188
|
-
|
|
133
|
+
> For the full analytics request capability (measures / facets / time-series fields, `by`, `sorts`,
|
|
134
|
+
> `ranges`, per-metric filters, defaults, and the widget → request mapping), see
|
|
135
|
+
> [`QUERYING.md`](./QUERYING.md).
|
|
136
|
+
|
|
137
|
+
### Using hooks with your own row type
|
|
189
138
|
|
|
190
139
|
```tsx
|
|
191
140
|
import { useLogsQuery } from '@gravitee/gamma-lib-observability';
|
|
192
141
|
|
|
193
|
-
// The generic parameter ensures data.entries is HttpProxyLog[]
|
|
194
142
|
const { data, isLoading } = useLogsQuery<HttpProxyLog>({
|
|
195
143
|
timeRange: { type: 'relative', period: '1h' },
|
|
196
144
|
filters: [{ field: 'status', label: 'Status', operator: 'in', value: ['500', '502'] }],
|
|
197
145
|
});
|
|
198
146
|
```
|
|
199
147
|
|
|
200
|
-
###
|
|
148
|
+
### Query key factory
|
|
201
149
|
|
|
202
150
|
Use `observabilityQueryKeys` when you need to invalidate or prefetch:
|
|
203
151
|
|
|
204
152
|
```ts
|
|
205
153
|
import { observabilityQueryKeys } from '@gravitee/gamma-lib-observability';
|
|
206
154
|
|
|
207
|
-
// Invalidate all observability queries
|
|
208
155
|
queryClient.invalidateQueries({ queryKey: observabilityQueryKeys.all });
|
|
209
|
-
|
|
210
|
-
// Invalidate a specific dashboard
|
|
211
156
|
queryClient.invalidateQueries({ queryKey: observabilityQueryKeys.dashboard('dash-123') });
|
|
212
157
|
```
|
|
213
158
|
|
|
214
|
-
|
|
159
|
+
---
|
|
215
160
|
|
|
216
|
-
|
|
161
|
+
## Advanced: Custom data sources
|
|
217
162
|
|
|
218
|
-
|
|
219
|
-
import { renderWithObservability } from '@gravitee/gamma-lib-observability/testing';
|
|
163
|
+
In most cases, the built-in HTTP adapters (auto-created from `baseUrl`) handle all data fetching. Implement a custom `DataSource` only when you need custom response mapping, typed row objects, or a non-standard API contract.
|
|
220
164
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
165
|
+
### Custom MetricsDataSource
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import type { MetricsDataSource } from '@gravitee/gamma-lib-observability';
|
|
169
|
+
|
|
170
|
+
export const myMetricsDataSource: MetricsDataSource = {
|
|
171
|
+
async fetchTimeSeries(request) {
|
|
172
|
+
/* ... */
|
|
173
|
+
},
|
|
174
|
+
async fetchFacets(request) {
|
|
175
|
+
/* ... */
|
|
176
|
+
},
|
|
177
|
+
async fetchMeasures(request) {
|
|
178
|
+
/* ... */
|
|
179
|
+
},
|
|
225
180
|
};
|
|
181
|
+
```
|
|
226
182
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
183
|
+
Pass it as the `dataSource` prop on `<observability.Routes>` to override the built-in adapter.
|
|
184
|
+
|
|
185
|
+
### Custom LogsDataSource
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import type { LogsDataSource } from '@gravitee/gamma-lib-observability';
|
|
189
|
+
|
|
190
|
+
export const myLogsDataSource: LogsDataSource<MyLogRow> = {
|
|
191
|
+
async fetchLogs(query) {
|
|
192
|
+
/* ... */
|
|
234
193
|
},
|
|
235
|
-
|
|
194
|
+
async getById(id, apiId, signal) {
|
|
195
|
+
/* ... */
|
|
196
|
+
},
|
|
197
|
+
};
|
|
236
198
|
```
|
|
237
199
|
|
|
238
|
-
|
|
200
|
+
Pass it as the `logsDataSource` prop on `<observability.Routes>`.
|
|
201
|
+
|
|
202
|
+
### Manual provider wiring
|
|
203
|
+
|
|
204
|
+
When embedding widgets or hooks **outside** the `observe/*` routes (e.g. a KPI section on an API detail page), you may need to provide data sources manually. Each provider is independent — nest them in any order under `QueryClientProvider`:
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
<QueryClientProvider client={queryClient}>
|
|
208
|
+
<CapabilityProvider capabilities={myCapabilities}>
|
|
209
|
+
<MetricsDataSourceProvider dataSource={myMetricsDataSource}>
|
|
210
|
+
<LogsDataSourceProvider dataSource={myLogsDataSource}>
|
|
211
|
+
{/* your custom pages using hooks directly */}
|
|
212
|
+
</LogsDataSourceProvider>
|
|
213
|
+
</MetricsDataSourceProvider>
|
|
214
|
+
</CapabilityProvider>
|
|
215
|
+
</QueryClientProvider>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
> **Note:** The nesting is a React Context requirement, not a semantic hierarchy — the providers are independent. `<observability.Routes>` creates these providers internally, so manual wiring is only needed for pages outside the managed route tree.
|
|
219
|
+
|
|
220
|
+
### Capabilities (RBAC)
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import type { DashboardCapabilities } from '@gravitee/gamma-lib-observability';
|
|
224
|
+
|
|
225
|
+
const myCapabilities: DashboardCapabilities = {
|
|
226
|
+
'observability.dashboards.read': true,
|
|
227
|
+
'observability.dashboards.write': false,
|
|
228
|
+
'observability.logs.read': true,
|
|
229
|
+
'observability.traces.read': false,
|
|
230
|
+
};
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
When no `CapabilityProvider` is present, all capabilities default to `false` (secure default).
|
|
239
234
|
|
|
240
235
|
## Canonical Types
|
|
241
236
|
|
|
@@ -665,41 +660,9 @@ Template properties:
|
|
|
665
660
|
| `requiredCapabilities` | `CapabilityKey[]` (opt.) | Template hidden when user lacks any listed capability |
|
|
666
661
|
| `dashboard` | `Dashboard \| (ctx) => Dashboard` | Static dashboard or factory receiving capabilities |
|
|
667
662
|
|
|
668
|
-
###
|
|
669
|
-
|
|
670
|
-
The recommended way to integrate observability into a Gamma module:
|
|
671
|
-
|
|
672
|
-
```tsx
|
|
673
|
-
import { defineObservabilityFeatures } from '@gravitee/gamma-lib-observability';
|
|
674
|
-
import { apiOverviewTemplate, aiTemplate } from './templates';
|
|
675
|
-
|
|
676
|
-
const observability = defineObservabilityFeatures({
|
|
677
|
-
features: {
|
|
678
|
-
dashboards: {
|
|
679
|
-
enabled: true,
|
|
680
|
-
templates: [apiOverviewTemplate, aiTemplate],
|
|
681
|
-
contextFilters: [{ field: 'API_TYPE', label: 'API Type', operator: 'in', value: ['MCP', 'LLM'] }],
|
|
682
|
-
scopeFilterField: 'API_TYPE',
|
|
683
|
-
},
|
|
684
|
-
logs: {
|
|
685
|
-
enabled: true,
|
|
686
|
-
contextFilters: [{ field: 'ENTRYPOINT', label: 'Entrypoint', operator: 'in', value: ['mcp-proxy', 'mcp'] }],
|
|
687
|
-
scopeFilterField: 'ENTRYPOINT',
|
|
688
|
-
},
|
|
689
|
-
},
|
|
690
|
-
nav: { label: 'Observability' },
|
|
691
|
-
});
|
|
692
|
-
|
|
693
|
-
// Returns:
|
|
694
|
-
// observability.Routes — React component to mount under your module's routes
|
|
695
|
-
// observability.navGroup — Navigation group descriptor for your sidenav
|
|
696
|
-
// observability.routeKeys — Array of route keys for breadcrumb integration
|
|
697
|
-
// observability.routes — Record of { path, label } for each enabled feature
|
|
698
|
-
// observability.resolveRouteKey — (pathname) => composite route key | null
|
|
699
|
-
// observability.breadcrumbSegments — (activeNavKey) => BreadcrumbSegment[] | null
|
|
700
|
-
```
|
|
663
|
+
### `defineObservabilityFeatures` — API reference
|
|
701
664
|
|
|
702
|
-
|
|
665
|
+
`defineObservabilityFeatures` is the entry point shown in [Quick start](#quick-start) step 1. It returns an `ObservabilityFeatures` object with the following members:
|
|
703
666
|
|
|
704
667
|
| Member | Type | Description |
|
|
705
668
|
| -------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
@@ -749,37 +712,19 @@ observability.breadcrumbSegments('llm-router'); // → null
|
|
|
749
712
|
- Returns `null` when `activeNavKey` is not an observability key.
|
|
750
713
|
- The host maps the segments onto its own breadcrumb renderer (e.g. `buildLinearBreadcrumbs` + `buildModuleNavPath`) and appends any 3rd-level title (dashboard name, log detail) itself.
|
|
751
714
|
|
|
752
|
-
###
|
|
715
|
+
### `ObservabilityRoutesProps` reference
|
|
753
716
|
|
|
754
|
-
|
|
755
|
-
import { Route, Routes } from 'react-router-dom';
|
|
717
|
+
See [Quick start](#quick-start) step 2 for the minimal mount. The full prop list is documented in [`INTEGRATION.md`](./INTEGRATION.md). Key props:
|
|
756
718
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
<observability.Routes
|
|
765
|
-
baseUrl="/management/v2/environments/DEFAULT"
|
|
766
|
-
tracesBaseUrl="/gamma/organizations/DEFAULT/environments/DEFAULT"
|
|
767
|
-
dataSource={myDataSource} // optional: overrides built-in HTTP metrics adapter
|
|
768
|
-
filterProviders={myProviders} // optional: overrides async filter definition fetch
|
|
769
|
-
logsDataSource={myLogsDataSource} // optional: overrides built-in HTTP logs adapter
|
|
770
|
-
logsColumns={myLogColumns} // required for auto-mounted logs page
|
|
771
|
-
logsOnRowClick={(entry) => navigate(`/logs/${(entry as MyLog).id}`)}
|
|
772
|
-
logsGetRowId={(row) => (row as MyLog).id}
|
|
773
|
-
/>
|
|
774
|
-
}
|
|
775
|
-
/>
|
|
776
|
-
</Routes>
|
|
777
|
-
</CapabilityProvider>
|
|
778
|
-
);
|
|
779
|
-
}
|
|
780
|
-
```
|
|
719
|
+
- `baseUrl` (required) — Gamma-scoped URL from `buildObservabilityBaseUrl`
|
|
720
|
+
- `http` — centralized auth config (`credentials`, `headers`)
|
|
721
|
+
- `logsColumns` — column definitions for the auto-mounted logs table
|
|
722
|
+
- `logsGetRowId` / `logsGetApiId` — row identity extractors for log detail
|
|
723
|
+
- `dataSource` / `logsDataSource` / `tracesDataSource` — optional overrides for the built-in HTTP adapters (see [Advanced: Custom data sources](#advanced-custom-data-sources))
|
|
724
|
+
- `filterProviders` — optional override for the async filter definition fetch
|
|
725
|
+
- `logsPage` — escape hatch for a fully custom logs page
|
|
781
726
|
|
|
782
|
-
When `logsColumns` are provided and the logs feature is enabled, the router auto-mounts `LogsExplorerPage`. If no `logsDataSource` prop is given, the library automatically builds one from `baseUrl` using `createHttpLogsSource` (same authentication
|
|
727
|
+
When `logsColumns` are provided and the logs feature is enabled, the router auto-mounts `LogsExplorerPage`. If no `logsDataSource` prop is given, the library automatically builds one from `baseUrl` using `createHttpLogsSource` (same authentication via the `http` prop).
|
|
783
728
|
|
|
784
729
|
### Routing Behavior
|
|
785
730
|
|
|
@@ -794,15 +739,7 @@ Filter state (active filters + time range) is persisted in URL query parameters
|
|
|
794
739
|
|
|
795
740
|
### Navigation Group
|
|
796
741
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
```tsx
|
|
800
|
-
const { navGroup } = observability;
|
|
801
|
-
// navGroup.label → 'Observability'
|
|
802
|
-
// navGroup.items → [{ key: 'observe/dashboards', title: 'Dashboards', icon: ChartLineIcon }]
|
|
803
|
-
```
|
|
804
|
-
|
|
805
|
-
Breadcrumbs are rendered by the calling module — the library does not own the layout shell — but the lib supplies the breadcrumb **data** (group + feature) via `observability.breadcrumbSegments(activeNavKey)`. See the [`ObservabilityFeatures` API reference](#observabilityfeatures-api-reference) above.
|
|
742
|
+
See [Quick start](#quick-start) step 3. `observability.navGroup` contains `{ label, items }` — only enabled features appear as items. Breadcrumbs are rendered by the calling module; the lib supplies the data via `observability.breadcrumbSegments(activeNavKey)` (see the [API reference](#defineobservabilityfeatures--api-reference) above).
|
|
806
743
|
|
|
807
744
|
---
|
|
808
745
|
|
|
@@ -814,13 +751,13 @@ Breadcrumbs are rendered by the calling module — the library does not own the
|
|
|
814
751
|
|
|
815
752
|
The simplest integration is via `defineObservabilityFeatures` + route props (see "Mounting Routes" above). The router auto-mounts `LogsExplorerPage` when `logsColumns` are passed to `<observability.Routes />`. The data source is resolved automatically from `baseUrl` via `createHttpLogsSource` — no explicit `logsDataSource` prop is needed unless you want to override the built-in adapter.
|
|
816
753
|
|
|
817
|
-
### Scope filtering via
|
|
754
|
+
### Scope filtering via API_TYPE
|
|
818
755
|
|
|
819
|
-
|
|
756
|
+
Logs scope by `API_TYPE`, the same vocabulary used by dashboards. Common values:
|
|
820
757
|
|
|
821
|
-
- **MCP**: `['
|
|
822
|
-
- **LLM**: `['
|
|
823
|
-
- **HTTP**: `['
|
|
758
|
+
- **MCP**: `['MCP']`
|
|
759
|
+
- **LLM**: `['LLM']`
|
|
760
|
+
- **HTTP**: `['HTTP_PROXY']`
|
|
824
761
|
|
|
825
762
|
To scope the logs page to a specific API type, set `contextFilters` and `scopeFilterField` in `LogsFeatureConfig`:
|
|
826
763
|
|
|
@@ -828,9 +765,9 @@ To scope the logs page to a specific API type, set `contextFilters` and `scopeFi
|
|
|
828
765
|
logs: {
|
|
829
766
|
enabled: true,
|
|
830
767
|
contextFilters: [
|
|
831
|
-
{ field: '
|
|
768
|
+
{ field: 'API_TYPE', label: 'API Type', operator: 'in', value: ['MCP'] },
|
|
832
769
|
],
|
|
833
|
-
scopeFilterField: '
|
|
770
|
+
scopeFilterField: 'API_TYPE',
|
|
834
771
|
}
|
|
835
772
|
```
|
|
836
773
|
|
|
@@ -974,8 +911,8 @@ export const myLogsDataSource: LogsDataSource<MyLog> = {
|
|
|
974
911
|
async fetchLogs(query) {
|
|
975
912
|
/* ... */
|
|
976
913
|
},
|
|
977
|
-
async getById(id, signal) {
|
|
978
|
-
const res = await fetch(`/api/logs/${id}`, { signal });
|
|
914
|
+
async getById(id, apiId, signal) {
|
|
915
|
+
const res = await fetch(`/api/logs/${id}?apiId=${apiId}`, { signal });
|
|
979
916
|
if (res.status === 404) return null;
|
|
980
917
|
return res.json();
|
|
981
918
|
},
|
|
@@ -1046,14 +983,24 @@ import { LogDetailDrawer } from '@gravitee/gamma-lib-observability';
|
|
|
1046
983
|
|
|
1047
984
|
function LogsPage() {
|
|
1048
985
|
const [selectedLogId, setSelectedLogId] = useState<string>();
|
|
986
|
+
const [selectedApiId, setSelectedApiId] = useState<string>();
|
|
1049
987
|
|
|
1050
988
|
return (
|
|
1051
989
|
<>
|
|
1052
|
-
<LogTable
|
|
990
|
+
<LogTable
|
|
991
|
+
onRowClick={(row) => {
|
|
992
|
+
setSelectedLogId(row.id);
|
|
993
|
+
setSelectedApiId(row.apiId);
|
|
994
|
+
}}
|
|
995
|
+
/>
|
|
1053
996
|
<LogDetailDrawer
|
|
1054
997
|
config={logDetailConfig}
|
|
1055
998
|
logId={selectedLogId}
|
|
1056
|
-
|
|
999
|
+
apiId={selectedApiId}
|
|
1000
|
+
onClose={() => {
|
|
1001
|
+
setSelectedLogId(undefined);
|
|
1002
|
+
setSelectedApiId(undefined);
|
|
1003
|
+
}}
|
|
1057
1004
|
onNavigatePrev={() => {
|
|
1058
1005
|
/* prev logic */
|
|
1059
1006
|
}}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export interface BuildObservabilityBaseUrlOptions {
|
|
2
2
|
/**
|
|
3
|
-
* When `true`, strips the origin from `
|
|
4
|
-
* pathname. Use this when a local dev proxy forwards `/
|
|
5
|
-
* to the real
|
|
3
|
+
* When `true`, strips the origin from `gammaBaseURL` and keeps only the
|
|
4
|
+
* pathname. Use this when a local dev proxy forwards `/gamma/…` requests
|
|
5
|
+
* to the real Gamma API — the browser must hit the proxy origin, not the
|
|
6
6
|
* remote one advertised in bootstrap.
|
|
7
7
|
*
|
|
8
8
|
* @default false
|
|
@@ -11,23 +11,23 @@ export interface BuildObservabilityBaseUrlOptions {
|
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Build the `baseUrl` that `<observability.Routes>` (and all built-in HTTP
|
|
14
|
-
* adapters) expect.
|
|
14
|
+
* adapters) expect. All observability endpoints now live under the Gamma API:
|
|
15
15
|
*
|
|
16
16
|
* ```
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* https://host/
|
|
20
|
-
* /
|
|
17
|
+
* gammaBaseURL orgId envId result
|
|
18
|
+
* ──────────────────── ───── ───── ──────
|
|
19
|
+
* https://host/gamma org-1 DEFAULT https://host/gamma/organizations/org-1/environments/DEFAULT
|
|
20
|
+
* /gamma org-1 DEFAULT /gamma/organizations/org-1/environments/DEFAULT
|
|
21
21
|
* ```
|
|
22
22
|
*
|
|
23
|
-
* With `{ useDevProxy: true }`, an absolute `
|
|
24
|
-
* its pathname before the
|
|
23
|
+
* With `{ useDevProxy: true }`, an absolute `gammaBaseURL` is reduced to
|
|
24
|
+
* its pathname before the org/env suffix is appended:
|
|
25
25
|
*
|
|
26
26
|
* ```
|
|
27
|
-
* https://host/
|
|
27
|
+
* https://host/gamma org-1 DEFAULT { useDevProxy: true } → /gamma/organizations/org-1/environments/DEFAULT
|
|
28
28
|
* ```
|
|
29
29
|
*
|
|
30
30
|
* The function is **pure** — it never fetches bootstrap or reads env vars.
|
|
31
31
|
*/
|
|
32
|
-
export declare function buildObservabilityBaseUrl(
|
|
32
|
+
export declare function buildObservabilityBaseUrl(gammaBaseURL: string, organizationId: string, environmentId: string, options?: BuildObservabilityBaseUrlOptions): string;
|
|
33
33
|
//# sourceMappingURL=build-observability-base-url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-observability-base-url.d.ts","sourceRoot":"","sources":["../src/build-observability-base-url.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gCAAgC;IAC/C;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CACvC,
|
|
1
|
+
{"version":3,"file":"build-observability-base-url.d.ts","sourceRoot":"","sources":["../src/build-observability-base-url.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gCAAgC;IAC/C;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,gCAAgC,GACzC,MAAM,CAcR"}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* When `true`, strips the origin from `gammaBaseURL` and keeps only the
|
|
4
|
-
* pathname. Use this when a local dev proxy forwards `/gamma/…` requests
|
|
5
|
-
* to the real Gamma API — the browser must hit the proxy origin, not the
|
|
6
|
-
* remote one advertised in bootstrap.
|
|
7
|
-
*
|
|
8
|
-
* @default false
|
|
9
|
-
*/
|
|
10
|
-
readonly useDevProxy?: boolean;
|
|
11
|
-
}
|
|
1
|
+
import { BuildObservabilityBaseUrlOptions } from './build-observability-base-url';
|
|
12
2
|
/**
|
|
3
|
+
* @deprecated Use {@link buildObservabilityBaseUrl} instead — both now produce
|
|
4
|
+
* identical Gamma-scoped URLs. This alias is kept for backward compatibility.
|
|
5
|
+
*/
|
|
6
|
+
export type BuildTracesBaseUrlOptions = BuildObservabilityBaseUrlOptions;
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Use {@link buildObservabilityBaseUrl} instead — both now produce
|
|
9
|
+
* identical Gamma-scoped URLs. This alias is kept for backward compatibility.
|
|
10
|
+
*
|
|
13
11
|
* Build the `tracesBaseUrl` that tracing HTTP adapters expect.
|
|
14
12
|
*
|
|
15
13
|
* Tracing endpoints live under the Gamma API, which is org-scoped:
|
|
@@ -21,13 +19,6 @@ export interface BuildTracesBaseUrlOptions {
|
|
|
21
19
|
* /gamma org-1 DEFAULT /gamma/organizations/org-1/environments/DEFAULT
|
|
22
20
|
* ```
|
|
23
21
|
*
|
|
24
|
-
* With `{ useDevProxy: true }`, an absolute `gammaBaseURL` is reduced to
|
|
25
|
-
* its pathname before the org/env suffix is appended:
|
|
26
|
-
*
|
|
27
|
-
* ```
|
|
28
|
-
* https://host/gamma org-1 DEFAULT { useDevProxy: true } → /gamma/organizations/org-1/environments/DEFAULT
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
22
|
* The function is **pure** — it never fetches bootstrap or reads env vars.
|
|
32
23
|
*/
|
|
33
24
|
export declare function buildTracesBaseUrl(gammaBaseURL: string, organizationId: string, environmentId: string, options?: BuildTracesBaseUrlOptions): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-traces-base-url.d.ts","sourceRoot":"","sources":["../src/build-traces-base-url.ts"],"names":[],"mappings":"AAAA,MAAM,
|
|
1
|
+
{"version":3,"file":"build-traces-base-url.d.ts","sourceRoot":"","sources":["../src/build-traces-base-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAElH;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,gCAAgC,CAAC;AAEzE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,yBAAyB,GAClC,MAAM,CAER"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-data-source.d.ts","sourceRoot":"","sources":["../../src/data-sources/http-data-source.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAY9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAuB/D,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACrE;AAsJD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"http-data-source.d.ts","sourceRoot":"","sources":["../../src/data-sources/http-data-source.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAY9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAuB/D,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACrE;AAsJD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,CAuDxG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-filter-source.d.ts","sourceRoot":"","sources":["../../src/data-sources/http-filter-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,4BAA4B,CAAC;AACxG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"http-filter-source.d.ts","sourceRoot":"","sources":["../../src/data-sources/http-filter-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,4BAA4B,CAAC;AACxG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAsD9D,MAAM,WAAW,YAAY;IAC3B,sBAAsB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACxE,aAAa,CACX,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,EAChD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CACpD;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,YAAY,CA8G3F"}
|