@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.
Files changed (46) hide show
  1. package/INTEGRATION.md +45 -55
  2. package/QUERYING.md +5 -5
  3. package/USAGE_GUIDE.md +178 -231
  4. package/dist/build-observability-base-url.d.ts +12 -12
  5. package/dist/build-observability-base-url.d.ts.map +1 -1
  6. package/dist/build-traces-base-url.d.ts +9 -18
  7. package/dist/build-traces-base-url.d.ts.map +1 -1
  8. package/dist/data-sources/http-data-source.d.ts.map +1 -1
  9. package/dist/data-sources/http-filter-source.d.ts.map +1 -1
  10. package/dist/data-sources/http-logs-source.d.ts +1 -13
  11. package/dist/data-sources/http-logs-source.d.ts.map +1 -1
  12. package/dist/data-sources/logs-data-source.d.ts +1 -1
  13. package/dist/data-sources/logs-data-source.d.ts.map +1 -1
  14. package/dist/filters/filter-provider.d.ts +6 -0
  15. package/dist/filters/filter-provider.d.ts.map +1 -1
  16. package/dist/hooks/query-keys.d.ts +1 -1
  17. package/dist/hooks/query-keys.d.ts.map +1 -1
  18. package/dist/hooks/use-log-detail-query.d.ts +1 -0
  19. package/dist/hooks/use-log-detail-query.d.ts.map +1 -1
  20. package/dist/hooks/use-logs-histogram-query.d.ts +0 -7
  21. package/dist/hooks/use-logs-histogram-query.d.ts.map +1 -1
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1460 -1498
  25. package/dist/logs/LogsExplorerPage.d.ts +1 -7
  26. package/dist/logs/LogsExplorerPage.d.ts.map +1 -1
  27. package/dist/logs/detail/components/LogDetailContent.d.ts.map +1 -1
  28. package/dist/logs/detail/components/LogDetailContextChart.d.ts +1 -3
  29. package/dist/logs/detail/components/LogDetailContextChart.d.ts.map +1 -1
  30. package/dist/logs/detail/components/LogDetailDrawer.d.ts +2 -1
  31. package/dist/logs/detail/components/LogDetailDrawer.d.ts.map +1 -1
  32. package/dist/logs/detail/components/LogDetailPage.d.ts.map +1 -1
  33. package/dist/logs/detail/types.d.ts +0 -7
  34. package/dist/logs/detail/types.d.ts.map +1 -1
  35. package/dist/logs/index.d.ts +0 -2
  36. package/dist/logs/index.d.ts.map +1 -1
  37. package/dist/routing/LogsRouteElement.d.ts +3 -3
  38. package/dist/routing/LogsRouteElement.d.ts.map +1 -1
  39. package/dist/routing/ObservabilityRoutes.d.ts +2 -1
  40. package/dist/routing/ObservabilityRoutes.d.ts.map +1 -1
  41. package/dist/routing/types.d.ts +47 -16
  42. package/dist/routing/types.d.ts.map +1 -1
  43. package/dist/styles/observability.css +1 -1
  44. package/package.json +5 -5
  45. package/dist/logs/analytics-filter-mapping.d.ts +0 -35
  46. 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.16.0
12
- - `@gravitee/graphene-charts` ^2.0.0
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
- ### 1. Wrap providers at module root
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
- ```tsx
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
- const queryClient = new QueryClient({
37
- defaultOptions: { queries: { staleTime: 30_000 } },
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
- <QueryClientProvider client={queryClient}>
43
- <CapabilityProvider capabilities={myCapabilities}>
44
- <MetricsDataSourceProvider dataSource={myMetricsDataSource}>
45
- <LogsDataSourceProvider dataSource={myLogsDataSource}>
46
- <TracesDataSourceProvider dataSource={myTracesDataSource}>
47
- <DashboardPersistenceProvider persistence={myPersistence}>
48
- {/* your routes */}
49
- </DashboardPersistenceProvider>
50
- </TracesDataSourceProvider>
51
- </LogsDataSourceProvider>
52
- </MetricsDataSourceProvider>
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
- ### 2. Define capabilities
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
- ```ts
62
- import type { DashboardCapabilities } from '@gravitee/gamma-lib-observability';
76
+ ### 3. Register navigation
63
77
 
64
- const myCapabilities: DashboardCapabilities = {
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
- The default (when no `CapabilityProvider` is present) is all capabilities set to `false` (secure default).
80
+ ```ts
81
+ const NAV_GROUPS = [...existingGroups, observability.navGroup];
82
+ ```
73
83
 
74
- ### 3. Implement DataSource adapters
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
- Each module implements the `MetricsDataSource`, `LogsDataSource<TRow>`, and/or `TracesDataSource` interfaces to translate its backend API responses into the expected shapes.
86
+ ## Testing
77
87
 
78
- #### Metrics (universal shape)
88
+ The lib exports a testing helper from the `./testing` subpath:
79
89
 
80
- ```ts
81
- import type { MetricsDataSource } from '@gravitee/gamma-lib-observability';
90
+ ```tsx
91
+ import { renderWithObservability } from '@gravitee/gamma-lib-observability/testing';
82
92
 
83
- export const myMetricsDataSource: MetricsDataSource = {
84
- async fetchTimeSeries(request) {
85
- const { metric, timeRange, filters, signal } = request;
86
- const response = await fetch(`/api/metrics/timeseries?metric=${metric}`, { signal });
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
- ```ts
109
- import type { LogsDataSource } from '@gravitee/gamma-lib-observability';
110
-
111
- // 1. Define your log row type
112
- interface HttpProxyLog {
113
- id: string;
114
- timestamp: string;
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
- ### 4. Use TanStack Query hooks
110
+ The helper wraps the component with `QueryClientProvider`, `CapabilityProvider`, and all DataSource providers you pass.
111
+
112
+ ---
149
113
 
150
- ```tsx
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
- Hooks available:
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
- #### Using `useLogsQuery` with your own row type
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
- ### 5. Query key factory
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
- ## Testing
159
+ ---
215
160
 
216
- The lib exports a testing helper from the `./testing` subpath:
161
+ ## Advanced: Custom data sources
217
162
 
218
- ```tsx
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
- const mockMetrics: MetricsDataSource = {
222
- fetchTimeSeries: vi.fn().mockResolvedValue([]),
223
- fetchFacets: vi.fn().mockResolvedValue([]),
224
- fetchMeasures: vi.fn().mockResolvedValue([]),
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
- const { getByText } = renderWithObservability(<MyComponent />, {
228
- dataSources: { metrics: mockMetrics },
229
- capabilities: {
230
- 'observability.dashboards.read': true,
231
- 'observability.dashboards.write': false,
232
- 'observability.logs.read': true,
233
- 'observability.traces.read': false,
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
- The helper wraps the component with `QueryClientProvider`, `CapabilityProvider`, and all DataSource providers you pass.
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
- ### Integration via `defineObservabilityFeatures`
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
- ### `ObservabilityFeatures` API reference
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
- ### Mounting Routes
715
+ ### `ObservabilityRoutesProps` reference
753
716
 
754
- ```tsx
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
- function ModuleApp() {
758
- return (
759
- <CapabilityProvider capabilities={userCapabilities}>
760
- <Routes>
761
- <Route
762
- path="observe/*"
763
- element={
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 as metrics/filters via the `http` prop or `HttpProvider`). If you need full control over the logs page layout, use the `logsPage` escape hatch instead (see below).
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
- Use `observability.navGroup` to register items in your module's sidenav:
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 ENTRYPOINT
754
+ ### Scope filtering via API_TYPE
818
755
 
819
- The Gravitee v2 logs search API supports filtering by `ENTRYPOINT` (`IN` operator). The entrypoint values map to API types:
756
+ Logs scope by `API_TYPE`, the same vocabulary used by dashboards. Common values:
820
757
 
821
- - **MCP**: `['mcp-proxy', 'mcp']`
822
- - **LLM**: `['llm-proxy']`
823
- - **HTTP**: `['http-proxy', 'http-get', 'http-post']`
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: 'ENTRYPOINT', label: 'Entrypoint', operator: 'in', value: ['mcp-proxy', 'mcp'] },
768
+ { field: 'API_TYPE', label: 'API Type', operator: 'in', value: ['MCP'] },
832
769
  ],
833
- scopeFilterField: 'ENTRYPOINT',
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 onRowClick={(row) => setSelectedLogId(row.id)} />
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
- onClose={() => setSelectedLogId(undefined)}
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 `managementBaseURL` and keeps only the
4
- * pathname. Use this when a local dev proxy forwards `/management/…` requests
5
- * to the real Management API — the browser must hit the proxy origin, not the
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
- * managementBaseURL environmentId result
18
- * ───────────────────── ───────────── ──────
19
- * https://host/management DEFAULT https://host/management/v2/environments/DEFAULT
20
- * /management DEFAULT /management/v2/environments/DEFAULT
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 `managementBaseURL` is reduced to
24
- * its pathname before the `/v2/environments/{envId}` suffix is appended:
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/management DEFAULT { useDevProxy: true } → /management/v2/environments/DEFAULT
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(managementBaseURL: string, environmentId: string, options?: BuildObservabilityBaseUrlOptions): string;
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,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,gCAAgC,GACzC,MAAM,CAcR"}
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
- export interface BuildTracesBaseUrlOptions {
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,WAAW,yBAAyB;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,yBAAyB,GAClC,MAAM,CAcR"}
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,CA+CxG"}
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;AAgD9D,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,CA6G3F"}
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"}