# Add Row Template Type Support for Alerts
## Overview
This PR adds support for configurable row template types in alerts,
allowing users to choose between **String** and **JSON** formats for row
templates. This provides flexibility in how alert data is formatted and
sent to destinations.
## Features
### Row Template Type Selection
- Added a new `row_template_type` field to alerts with two options:
- **String**: Traditional string-based templates with variable
interpolation
- **JSON**: Structured JSON templates for programmatic consumption
### Database Layer
- Uses efficient `smallint` (i16) storage: `0` for String, `1` for JSON
- Added migration `m20251118_000001_add_alert_row_template_type` with
backward compatibility (defaults to String)
- Includes support for PostgreSQL, MySQL, and SQLite
### API Layer
- Returns enum string representation (`"String"` or `"Json"`) in API
responses
- Full support in GET, CREATE, and UPDATE alert endpoints
### UI Changes
- Added toggle button in alert creation/editing form to switch between
String and JSON template types
- Dynamic placeholder text based on selected template type
- Persists user's template type selection in the database
## Usage Example
### String Template (Default)
When creating an alert with row template type set to **String**:
```
Template Type: [String] JSON
Row Template: Alert triggered: {alert_name} at {timestamp} Affected user: {user_id} Error count: {error_count}
```
### JSON Template
When creating an alert with row template type set to **JSON**:
```
Template Type: String [JSON]
Row Template: { "alert": "{alert_name}", "timestamp": "{timestamp}", "user": { "id": "{user_id}", "name": "{user_name}" }, "metrics": { "error_count": {error_count}, "severity": "{severity}" } }
```
The JSON template type automatically parses and validates JSON
structure, making it ideal for:
- Webhook integrations that expect JSON payloads
- Structured logging systems
- API endpoints requiring specific JSON schemas
- Downstream systems that need programmatic access to alert data
## Technical Details
### Architecture
- **Database**: Stores as `smallint` (0 or 1) for efficiency
- **Service Layer**: Uses `RowTemplateType` enum throughout application
logic
- **API**: Serializes enum as strings (`"String"`, `"Json"`)
- **Frontend**: TypeScript interface uses string type with toggle UI
component
### Backward Compatibility
- Existing alerts without `row_template_type` default to `String`
- Migration adds column with `DEFAULT 0` ensuring zero downtime
- API handles both old and new alert formats seamlessly
## Testing
- Added unit tests for database migration (PostgreSQL, MySQL, SQLite)
- Tested enum serialization/deserialization
- Verified UI toggle behavior and data persistence
- Confirmed backward compatibility with existing alerts
<img width="1070" height="770" alt="Screenshot 2025-11-19 at 5 46 34 PM"
src="https://github.com/user-attachments/assets/900edb1c-815e-4240-91e2-50a1a582a9b0"
/>
1. we have created header component which will seperate out the header
part from mainlayout
2. introduced custom dark logo feature , it will fallback to light mode
logo if dark mode logo is not there
When `ZO_USAGE_REPORT_TO_OWN_ORG` is enabled (default: true), triggers
are written to both _meta and originating orgs. This caused schema
divergence where some orgs missing fields like 'error', breaking
dashboard queries.
Add ensure_triggers_stream_schema() to auto-sync missing TriggerData
fields before ingestion. Runs once per stream, logs missing fields, and
updates defined_schema_fields gracefully without blocking ingestion.
Fixes queries like: SELECT error FROM triggers WHERE status='failed'
---------
Co-authored-by: Ashish Kolhe <ashish.j.kolhe@gmail.com>
https://github.com/openobserve/openobserve/pull/8876 had made
this variable private, resulting in failed enterprise builds.
It also removed one of the imports causing build failure.
This commit reverts those specific changes.
- Fix panic on path canonicalization in check_has_pending_files()
- Implement proper recursive directory checking for parquet files
- Add exponential backoff to draining loop (50ms -> 1s)
- Validate query parameter strictly in enable endpoint to prevent accidental node disablement
These changes address critical robustness issues identified in the code review:
1. Prevents potential panics during shutdown when WAL path is missing
2. Ensures correct pending file detection instead of assuming all subdirectories have files
3. Reduces CPU usage during drain with exponential backoff
4. Prevents unintentional node disablement from invalid/missing parameters
Implements cloud-agnostic graceful shutdown mechanism to support
Kubernetes preStop hooks and other orchestration platforms.
Changes:
- Add IS_INGESTER_DRAINING global flag with atomic operations
- Enhance /enable?value=false to trigger flush and set draining mode
- Add /drain_status endpoint to monitor shutdown readiness
- Modify parquet upload job to prioritize draining mode
- Exit upload loop when all files are uploaded to S3
API Usage:
- PUT /node/enable?value=false - Initiates drain (flushes memory, sets flag)
- GET /node/drain_status - Returns readyForShutdown status
Benefits:
- Eliminates fixed 900s wait in Helm charts
- Cloud-agnostic (works with K8s, ECS, Docker Swarm, systemd)
- Data-safe: ensures all WAL files uploaded before shutdown
There is a potential deadlock of usage report, it will resend to queue
when ingest failed. but if the queue is full, the resend will block and
waiting consume, but the consumer is itself, then it deadlock.
I saw a lot of logs like this:
```
DEBUG openobserve::service::db::schema: [Schema:watch] Received event: Put(EventData { key: "/schema/default/metrics/http_server_duration", value: Some(b""), start_dt: None
```
This PR optimized the metadata check logic also try to debug this case.
resolves https://github.com/openobserve/openobserve/issues/8991
### Summary
- Introduces `is_background()` method in `SearchEventType`.
- Identifies **Alerts**, **Reports**, and **DerivedStreams** as
background tasks.
- Routes these tasks to a dedicated **`BACKGROUND`** work group.
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
Currently in the alert manager, we run a keep alive thread for every
scheduled job pulled, so that if the timeout for the job is near and the
job is still in progress, we can increase the timeout a bit so that the
job can complete. But in edge cases, if the job itself is complete, but
the keep-alive thread is still not stopped, it will keep running the
keep alive thread forever.
Hence, a limit is added to the keep alive thread, so that it stops after
the timeout.
# PR Type
Enhancement
# Description
The columns in the Alerts and Pipelines History are augmented to be
sortable. The backend endpoint is updated accordingly too.
---------
Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
with this PR we add OR operator support in pipeline conditions along
with the ability to nest conditions, creating complex conditions
quickly. existing conditions will be treated as legacy conditions and
still be honoured in the new evaluation logic.