Commit Graph
11 Commits
Author SHA1 Message Date
ByteBaker 4c080dfd5f fix: alert graph edges not rendering due to timestamp equality (#10347)
### **User description**
## Problem

Fixes openobserve/o2-enterprise#1229

Alert graphs were not rendering edges (arrows) when nodes had identical
timestamps, causing the topology graph to show nodes without
connections.

## Root Cause

The edge creation logic used strict timestamp inequality (`<`, `>`),
which failed when alerts fired at the exact same microsecond. This
commonly occurs with:
- High-frequency alerting
- Bulk alert ingestion
- Simulated/test data with fixed timestamps
- Clock resolution limitations

## Solution

Added timestamp tiebreaker logic using node index (insertion order) for
all three edge creation scenarios:

1. **Same-service temporal edges**: Connect to most recent previous
node, use index as tiebreaker
2. **Cross-service temporal edges**: Connect to chronologically closest
node, use index as tiebreaker
3. **Service dependency edges**: Connect related services, use index as
tiebreaker

## Changes

- `src/service/alerts/incidents.rs`: Updated 3 edge creation locations
with timestamp + index comparisons

## Impact

- ✅ Edges now created even when alerts have identical timestamps
- ✅ Deterministic behavior based on insertion order
- ✅ Graph visualization shows proper alert flow with arrows
- ✅ Root cause analysis now possible

## Testing

- Verified code compiles successfully
- Manual testing recommended with alerts at same timestamp


___

### **PR Type**
Bug fix


___

### **Description**
- Add tiebreaker for equal timestamps

- Ensure deterministic topology edge creation

- Fix missing incident graph arrows


___

### Diagram Walkthrough


```mermaid
flowchart LR
  A["New alert node added"] --> B["Find candidate prior/next nodes"]
  B --> C["Compare (first_fired_at, node_index)"]
  C --> D["Create temporal/dependency edges deterministically"]
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>incidents.rs</strong><dd><code>Deterministic edge
creation for equal timestamps</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

src/service/alerts/incidents.rs

<ul><li>Add index-based tiebreaker for same-service edges<br> <li> Allow
dependency edges when timestamps equal<br> <li> Refine cross-service
temporal matching with index<br> <li> Update ordering keys to include
node index</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/10347/files#diff-2411d921fd8b8783c049deea11da06726ed986550d405477d486234892353ca9">+17/-5</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___
2026-02-03 20:39:52 +05:30
ByteBakerandsai nikhil kethe 7df19cb00a fix: incident graphs and service graphs improvements (#10318)
### **User description**
## Changes

### 1. Reduce alert graph edge explosion
- Modified temporal edge logic to prevent O(n²) growth
- Changed same-service edges to only connect to most recent previous
alert
- Changed cross-service temporal edges to connect to chronologically
closest alert
- **Impact**: 88% reduction in edges (16 instead of 136 for 17 alerts)

### 2. Improve correlation error handling
- Added fallback mechanism when service registry is empty
- Better error messages for correlation failures
- Enhanced incident detail view with clearer feedback

**Files modified:**
- `src/service/alerts/incidents.rs`
- Incident correlation handling


___

### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Prevent alert topology edge explosion

- Add frontend fallback incident correlation

- Improve correlation tab empty/error UX

- Share time/stream state across tabs


___

### Diagram Walkthrough


```mermaid
flowchart LR
  A["Incident alerts ingested"] 
  B["Topology enrichment"]
  C["Same-service temporal chain"]
  D["Cross-service edges"]
  E["ServiceGraph tab shared state"]
  F["Incident detail correlation"]
  G["FQN-priority drift detection"]
  H["Frontend fallback correlation"]
  A -- "build graph" --> B
  B -- "temporal edges" --> C
  B -- "dependency edges" --> D
  E -- "share datetime/stream" --> B
  F -- "fetch correlated streams" --> G
  G -- "if not drift" --> H
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>convertTraceData.ts</strong><dd><code>Simplify
service-graph tree request metrics</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

web/src/utils/traces/convertTraceData.ts

<ul><li>Use incoming edge metrics for non-root<br> <li> Root sums
outgoing edge request counts<br> <li> Default root error rate to
zero<br> <li> Keep connection count as in+out</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/10318/files#diff-f236b4107f8b11c8281dec8279238d02309a3c958bd1ee2076716df56b00c057">+5/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>incidents.rs</strong><dd><code>Limit temporal topology
edges to nearest alerts</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

src/service/alerts/incidents.rs

<ul><li>Same-service temporal edge targets most recent prior<br> <li>
Keep full ServiceDependency edges when SG edge exists<br> <li> For
non-dependent services, link to closest later alert<br> <li> Avoid
duplicate edges with type-specific checks</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/10318/files#diff-2411d921fd8b8783c049deea11da06726ed986550d405477d486234892353ca9">+80/-47</a>&nbsp;
</td>

</tr>
</table></td></tr><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>IncidentDetailDrawer.vue</strong><dd><code>Add fallback
correlation and improve tab states</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

web/src/components/alerts/IncidentDetailDrawer.vue

<ul><li>Show refresh header only when streams exist<br> <li> Unify
error/no-data states with clearer messaging<br> <li> Detect FQN priority
changes post-incident creation<br> <li> Build frontend fallback
correlation from schema mapping</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/10318/files#diff-6973d58a5f49658b07d3533d4db5d32cc6430433b51732481e7497243dadb0b0">+217/-72</a></td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>ServiceGraph.vue</strong><dd><code>Share Service Graph
time/stream with traces state</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

web/src/plugins/traces/ServiceGraph.vue

<ul><li>Bind datetime picker to <code>searchObj.data.datetime</code><br>
<li> Use shared <code>searchObj.data.stream.*</code> for stream
lists<br> <li> Remove local stream/time state and duplicate stream
loading<br> <li> Simplify empty-state guidance and code styling</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/10318/files#diff-da1aabfbe74e57c02db16fc5d3e00cd76dc76bf0ad9b57f9dfda7d6d9da06129">+50/-181</a></td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___

---------

Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
2026-02-02 20:01:34 +05:30
ByteBaker e0a2209ebe feat: add DateTime picker to service graph and rename tab (#10283)
### **User description**
## Summary
Adds DateTime picker to service graph allowing users to select custom
time ranges for visualization. Also rename the tab from `Service Maps`
to `Service Graphs`.

## Changes
- Add DateTime component to ServiceGraph.vue
- Update service graph service to pass start_time/end_time parameters
- Backend API already supports custom time range queries
- Rename tab name and address to service graphs (from service maps)
2026-01-30 17:58:30 +05:30
ByteBaker 44e203bf5e fix: improve service graph peer service extraction and add latency visualization
Backend changes:
- Remove server_address from peer attribute candidates to reduce cardinality
- Use only peer_service, db_name, and db_system for peer identification
- Skip streams without peer attributes instead of using fallback
- Filter out empty client/server names in SQL queries
- Remove 'internal' fallback for INTERNAL spans

Frontend changes:
- Add P50/P95/P99 latency metrics to edge tooltips
- Add latency-based color coding (errors priority, then latency thresholds)
- Display formatted latency values (auto-converts ns to ms/s)
- Preserve stream dropdown options when switching between streams
2026-01-13 09:57:27 +05:30
ByteBaker 76f33b38c7 fix: remove http_url from service graph peer attributes (#9817)
## Summary
- Removes `http_url` from peer attribute candidates to fix massive node
cardinality
- Fixes API to respect configured time range instead of hardcoded 60
minutes
- Fixes tree view to display all nodes including disconnected components
- Changes default visualization to graph view

## Problems Fixed

### 1. Node Explosion from URL Variations
Service graph was creating separate nodes for every URL variation with
different query parameters or path parameters:
- `/api/products/1YMWWN1N4O`, `/api/products/9SIQT8TOJO`, etc.
- `?contextKeys=books`, `?contextKeys=travel`, etc.

This caused hundreds of nodes instead of a clean service topology.

### 2. API Ignoring Configuration
API hardcoded 60-minute query window, ignoring the configured
`service_graph.query_time_range_minutes` setting.

### 3. Tree View Missing Nodes
Tree view only showed nodes reachable from root nodes (no incoming
edges), hiding services in cycles or disconnected components.

## Solutions

### 1. Use server_address Instead of http_url
Now uses `server_address` attribute (hostname only) following
OpenTelemetry HTTP semantic conventions for service identification.

### 2. Respect Configured Time Range
API now uses same configured time window as processor for consistency.

### 3. Virtual Root for Tree View
Creates invisible virtual root node to display all disconnected service
trees in ECharts.

### 4. Better Default UX
Graph view is now the default with reordered buttons (Graph View first).
2026-01-02 20:34:50 +05:30
Bhargav 890e8d7669 fix: Node package upgrade v1.8 (#9773)
### **PR Type**
Enhancement


___

### **Description**
- Upgrade Tailwind CSS from v3.4.4 to v4.1.18

- Bump rudder-sdk-js from 2.48.43 to 2.52.7


___



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Dependencies</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>package.json</strong><dd><code>Bump dependency versions
in package.json</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

web/package.json

<ul><li>Updated <code>tailwindcss</code> version to ^4.1.18<br> <li>
Updated <code>rudder-sdk-js</code> version to ^2.52.7</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/9773/files#diff-b861012a5dd72b8a9f3281b7cf09f5a779c98569d040b1bbc1db50f1b15e7cce">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___
2025-12-29 20:00:34 +05:30
ByteBaker 14212b7064 fix: schema-based peer attribute detection for service graph
- Check schema for peer attributes before querying
- COALESCE priority: peer_service > server_address > db_name > db_system > http_url
- Fallback to 'internal' if no peer attributes
- Support INTERNAL spans with exclude config
- Improved UI empty state with troubleshooting
2025-12-03 16:40:17 +05:30
ByteBaker ada80858e8 feat: migrate service graph to SQL-based daemon architecture
Replace in-memory EdgeStore with daemon-based architecture that periodically
queries trace streams using SQL aggregation in DataFusion.

Architecture:
- Daemon runs in compactor job every 1 hour (default, configurable)
- Queries last 60 minutes of trace data (configurable window)
- Uses DataFusion SQL with CTE for efficient aggregation
- Calculates p50, p95, p99 percentiles using approx functions
- Writes aggregated edges to internal `_o2_service_graph` stream
- Zero impact on trace ingestion performance

Key Changes:
- Add `processor.rs` with SQL-based daemon that queries trace streams
- Add `aggregator.rs` to write SQL results to `_o2_service_graph` stream (uses json! macro)
- Refactor `api.rs` to query pre-aggregated data from stream
- Move business logic to enterprise repo (`build_topology()`, `span_to_graph_span()`)
- Remove ALL inline processing during trace ingestion
- Delete in-memory EdgeStore, worker threads, and buffering code
- Feature-gated for enterprise builds with non-enterprise stubs

SQL Query:
- CTE extracts client/server from span_kind ('2'=SERVER, '3'=CLIENT)
- Aggregates by (client, server) with COUNT, percentiles, error rate
- Filters: span_kind IN ('2','3') AND peer_service IS NOT NULL

Configuration:
- O2_SERVICE_GRAPH_ENABLED (default: false)
- O2_SERVICE_GRAPH_PROCESSING_INTERVAL_SECS (default: 3600) - Daemon run frequency
- O2_SERVICE_GRAPH_QUERY_TIME_RANGE_MINUTES (default: 60) - Query window size

Technical Details:
- Stream name: `_o2_service_graph` (internal stream)
- Edge timestamp: Uses query end time for API compatibility
- Span kinds: '2' (SERVER), '3' (CLIENT) as VARCHAR in parquet
- Percentiles: approx_median(), approx_percentile_cont(0.95), approx_percentile_cont(0.99)
2025-12-01 17:06:53 +05:30
ByteBaker bb37f8f1af feat: add comprehensive service graph visualization with tree/graph views
Backend:
- Add `stream_name` parameter to service graph query API for multi-stream filtering
- Pass `stream_name` through `handle_otlp_request` to service graph tracking
- Filter Prometheus metrics by both `org_id` and optional `stream_name`
- Update API documentation with stream filtering examples

Frontend:
- Add tree view and graph view visualization modes with toggle
- Implement tree layouts: horizontal, vertical, and radial
- Implement graph layouts: force-directed and circular
- Add stream selector dropdown to filter metrics by trace stream
- Add auto-refresh toggle with configurable interval (5-300 seconds)
- Refactor graph rendering to use `ChartRenderer` component with ECharts
- Implement D3-force physics simulation for force-directed layout
- Add `convertServiceGraphToTree` and `convertServiceGraphToNetwork` utilities
- Preserve node positions during graph updates to prevent re-layout jitter
- Use incremental updates (`notMerge: false`) for stable graph view
- Store user preferences (visualization type, layout, stream filter) in localStorage
- Update `ChartRenderer` to respect `notMerge` and `lazyUpdate` flags from props

Dependencies:
- Add `d3-force` for force-directed graph layout calculations
- Add `@types/d3-force` for TypeScript support
- Add `d3-quadtree` for spatial indexing in force simulation
2025-11-14 16:19:04 +05:30
Omkar Kesarkhane f84a760a63 fix: Service Graph UI improvements (#8958) 2025-11-05 13:10:29 +05:30
ByteBaker e4e7274ec8 feat: add service graph as enterprise-only feature
Service graph automatically discovers service topology from distributed traces.

OSS includes:
- API routing endpoints (gated with enterprise feature flag)
- UI components (functional only with enterprise backend)
- Configuration options

Enterprise includes:
- 256-shard concurrent edge store with LRU eviction
- Span matching and processing logic
- Prometheus metrics and background workers
2025-10-30 17:20:21 +05:30