mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-06 08:09:24 +00:00
cd4e269dcdf5ea26668bc60d460d091cdb3d74c3
39
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bbb0da9309 | fix(billing): compact Plans page and show pay-as-you-go vs annual pricing (#15559) | ||
|
|
5f97a00d13 |
feat(announcements): banner editor with custom styles, link buttons and scheduling (#15194)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
abc6c1c797 |
feat(synthetics): subtests — embed a browser test in another, and extract steps into one (#14645)
Co-authored-by: Loakesh Indiran <rustyloaki@gmail.com> Co-authored-by: Loakesh Indiran <66478092+Loaki07@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
9a1911322a |
feat: variable suggestions on {{ in text fields (LLM Playground and Synthetics) (#14747)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
dfc3c8e02d |
feat(synthetics): shared variables, environments, and per-environment results (#14254)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Loakesh Indiran <rustyloaki@gmail.com> Co-authored-by: Loakesh Indiran <66478092+Loaki07@users.noreply.github.com> |
||
|
|
478824a41e | feat(alerts): add curated alerts from the library in bulk (#14054) | ||
|
|
eedc773cd7 | chore: remove action scripts / action server (#14000) | ||
|
|
fea71e02d4 |
feat(alerts): alert library — browse, preview and install curated alerts (#13922)
## Alert Library A curated catalog at `/alert-library`: browse packs of ready-made alerts, see which ones can actually run against the streams this org already receives, preview a verdict against real data, and install one or many. The library is a **peer page** of Alerts / Notification Destinations / Templates — flat routing, presented as tabs via a shared `AlertSectionTabs` in `OPageLayout #header-tabs` (the pattern `PipelineSectionTabs` already ships). ### What landed, by phase | Phase | What | | --- | --- | | Data layer | S3 manifest fetch, cache, readiness resolution (`useAlertLibrary`, `constants/alertLibrary`, `types/alertLibrary`) | | Gallery | Rail (packs / categories, multi-select, segmented switch), stat-strip availability facets, cards | | Drawer | Detail view with query preview and customizable tunables | | Install | Bulk-install wizard — destination selection, per-alert tunables, stale-session hardening | | Prefill | Carry a library alert (query, trigger, threshold, severity) into the alert editor | ### Design decisions worth knowing - **Rail navigates, strip filters.** Availability is deliberately not in the rail — carrying both overflowed it and pushed a facet group below the fold. - **Colour marks the exception only.** No "Ready" pill (it would describe ~75 of 86 cards and signal nothing); only unusable cards carry a label. - **A failed `/streams` call leaves readiness unknown**, rather than claiming "none of your data matches" — that claim would be about the request, not the org, and it is the most alarming thing this page can say. Counts read `—` until there is an answer, and a failed *refresh* keeps the verdict it already had. - **No "Installed" tile** — installed detection doesn't exist yet, and a tile reading a permanent zero is dishonest UI. - **`severity: warning` renders as `medium`** — the badge group's scale is critical/high/medium/low/info, and medium is the amber it also gives P3, which is exactly the priority a warning alert installs as. - Pack and category names come from the manifest, so they render as `raw()` data — a pack added upstream needs no frontend release. ### Design-system changes (used by the library, applied app-wide) - **`warning-quiet` badge tone** — one variant whose values differ by theme: the soft amber wash in light, a neutral chip in dark. Neither the filled amber chip nor the neutral one was right in both, because the two ramps aren't symmetric. - **Border tokens now meet WCAG 2.1 SC 1.4.11.** Every border token measured under 3:1 (`border-strong` was 2.52:1). `border-default` firms to grey-300 and controls get a token that clears 3:1. - Nav: Reliability's flyout groups its four alerting entries under one **Alerts** header, declared in the same order as the tab strip those pages carry. Flyout levels are sized by depth. - `sensors-off` icon added to the `OIcon` registry. ### Fixes that rode along - **metrics**: a shared URL whose `metrics_data` blob omits panel query fields no longer blanks the whole metrics page — blob queries are filled out to the panel schema before being laid over. - **dashboards**: a PromQL series with no legend template was named `JSON.stringify(metric)`, so fifty series read identically for the width of the chip. Series are now named by the labels that actually differ, preferring the ones that say *which workload* it is (namespace / service / pod / host). Correlation's semantic groups refine that when loaded, but nothing is fetched to render a chart — that endpoint is enterprise-only and a chart must render the same on OSS. - **alerts**: preview evaluates against the alert's real trigger; deleting a row no longer reloads the list behind it; peer tabs no longer shift when switching alerting pages. - **ui**: badge-only select options no longer render bold. ### Tests - `test(search)`: pins the streaming-aggregate **wire contract** at the HTTP boundary. Under streaming aggregates each partition carries the cumulative merged state (last frame is the answer) while ordinary partitions are disjoint and must be summed. No pytest had ever received `streaming_aggs: true` — the emitter could have flipped to per-partition deltas with the whole suite green while dashboards, Logs and the alert preview all silently over-counted. - `test(e2e)`: four helpers that passed only while an org stayed small — an assertion reading past a 20-row page, an unfiltered `OSelect` that virtualises past 50 entries, a tab click landing on the rename pencil, and two builder tests asserting on whichever metric sorted first. - New unit specs across the library components, composable, facets, tunables and install path. ### Notes - **i18n**: en-US only; CI generates the other 14 locales. - **No backend changes** — this branch is entirely `web/` plus test helpers. |
||
|
|
cb1b064a5d |
fix(synthetics): support to read a run's evidence without leaving the step (#13879)
## What Makes the evidence a synthetic browser check captures readable **where you already are**, instead of one tab away. Two related changes on the run-detail view: **1. An evidence row opens to its full record.** The table renders three fields the probe already captures and nothing displayed: the stack trace on a page error, the resource type, and the first-party flag. Plus the full URL — the row strips the host and then truncates, so a login URL died mid-query-string with no way to see the rest. **2. The step expansion's "Page activity" card now hosts that same table.** It used to show five severity-ranked rows and a `5 of 136` count — a card whose headline metric was its own incompleteness. It now renders the step's whole bucket with the same header, sorting, row expansion, filters, wrap and paging the Evidence tab has. Supporting work: the filter row is extracted into one component shared by both surfaces, so they cannot drift onto different controls; and the Evidence tab's step scope is a select you can change rather than a banner you can only dismiss. ## Why Every question past "was there anything?" cost a tab switch, and the correlation you arrived with — this step, this failure — had to be rebuilt by hand against a step filter. ## Notable fixes found along the way - **The Step column was sortable but sorted nothing.** It had no accessor, so the comparator read a field the row does not have, compared `undefined` to `undefined`, and left every row in place while the header showed a working arrow. - **The step expansion's content column had no width clamp.** As a flex item it kept its content's intrinsic width, so a long URL pushed it past the container and every card in it overflowed — and `truncate` and `overflow-x-auto` both went inert, since each needs a bounded parent. Measured at 1487px inside a 1000px container. - **Expand chevrons did not line up.** The row status rail's class also insets the first cell, so rows without a rail sat half a rem left. Benign rows now reserve the slot transparently. - **"Took" was never right-aligned** — the class sat on an inline span, where it aligns nothing. ## Testing `components/synthetics/`, `views/synthetics/`, `composables/synthetics/`, `utils/synthetics/` — **1398 passing**. `type-check`, `lint:design:strict` and `format:check` all clean. New behavioural coverage where it was thin: sorting is driven through the header and asserted on rendered row order rather than on column config, which is what let the non-functional Step sort ship. ## Reviewer notes - `EvidenceEvents.vue` is shared by both surfaces. The only differences left are the Step column and the page size — everything else is deliberately identical. - The step select is gated on being passed options, which is how it stays off the step card, where the step is already the scope. A test on each side pins that. - The per-step card's five-row cap is deliberately removed; pagination bounds the height instead, which bounds the card *and* keeps every event reachable in place. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
c53a16b262 |
fix: script i18n (#13840)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
ddb67f3efb |
fix(synthetics): record from a specific step, and stop silently downgrading recorded actions (#13799)
Supersedes #13777, which carried the record-from-step commits alone. Closing that in favour of this, because the two changes land in the same three files (`types/synthetics.ts`, `useSyntheticsRecorder.ts`, `JourneySteps.vue`) and reviewing them apart means resolving the same conflict twice. ## Problem **A recorded hover was stored as a click.** Playwright 1.56 added `hover` to the recorder's action model, reachable from its "Choose action" picker. The extension's action mapper seeds every step with `action: 'click'` as a placeholder for its switch to overwrite, and returned that placeholder from `default:` — so any action name the switch did not know became a click the author never performed. On the usual hover target — a nav trigger, a dropdown opener — clicking it can navigate or submit. The run still reports green. There are three separate guards meant to stop exactly this, and none of them fired, because the relabel happens upstream of all of them: | Guard | Why it missed | |---|---| | `UNSUPPORTED_REPLAY_ACTIONS` (extension) | step already said `click` | | `RETIRED_ACTIONS` → `isStorableAction` | step already said `click` | | `V2_STEP_ACTIONS` (Rust validation) | `click` is valid | The same picker offers **Right click** and **Double click** as explicit choices. Both were flattened too: `click_count` was dropped by the mapper and never existed downstream, and the probe's executor called `locator.click({ timeout })` while reading neither `button` nor `click_count`. A deliberately recorded right click replayed as a left click; a double click as a single one. **Recording could only start from scratch.** Fixing step 12 of a 15-step journey meant re-recording all 15. ## Change **Record from a specific step.** Each step gets a record action that replays the prefix before it, then flips the recorder into insert mode at that point. A restore that cannot reach the requested step reports where it stopped (`prefixFailed`) rather than silently recording from the wrong place. **Every action Playwright can record is now stored and replayed as itself.** - `hover` is a first-class v2 action — mapped, stored, validated, and executed by `Locator.hover` in the probe and `Frame.hover` in the extension player. - `button` and `click_count` travel to storage, so right click and double click replay as recorded. - An action name the mapper does not know now **throws** instead of returning the `click` placeholder. This is the part that is not hover-specific: upstream added one action in nine minors and will add more, and the next one must be a deliberate decision rather than a silent downgrade. **The extension handshake reports capabilities, not just presence.** `getStatus` now returns `extVersion` and a `capabilities` array; O2 gates affordances on `hasCapability()` with a defined pre-handshake fallback, and warns when the installed build is older than the minimum. Previously the protocol carried no version at all — Chrome updates the extension independently of when O2 deploys, so the two could disagree about the wire with no way to say so. **Two dead message declarations, opposite problems.** `setSources` no longer exists in playwright-core (sources arrive alongside the actions), so its declared variant could never fire — while its `generatedCode` field is exactly what an eject-to-code feature would reach for. Deleted. `elementPicked` is the reverse: it fires on every "Pick locator" and every click in inspecting mode, and was being discarded, which made inspect mode a dead end. Now kept. ### Compatibility `button` and `click_count` are optional with defined absent-behaviour — absent means a single left click. Every journey stored today stays valid, means the same thing, and serialises byte-identically. **No schema version bump and no migration.** A test pins that rather than leaving it as an intention. `hover` is a new vocabulary entry with no default, so the probe must be able to execute one before O2 is allowed to store one — the probe change ships first. ## Implementation | File | | |---|---| | `src/config/src/meta/synthetics.rs` | `hover` joins `V2_STEP_ACTIONS`/`V2_ELEMENT_ACTIONS`; `button` and `click_count` added to `BrowserStepV2` with validation (`left\|middle\|right`, `1..=3`) | | `web/src/types/synthetics.ts` | `button`/`clickCount` on both step types; `extVersion` + `capabilities` on `RecorderStatus`; `setSources` variant deleted and `elementPicked` typed; `prefixFailed` and insert-mode fields on `recordingStarted` | | `web/src/utils/synthetics/mapRecordedStep.ts` | promotes `button`/`clickCount` from the wire, like every other stored field | | `web/src/utils/synthetics/buildV2Steps.ts` | `hover` in `ACTION_TO_V2`; crosses camelCase → snake_case for the two click fields | | `web/src/constants/synthetics.ts` | `hover` out of `RETIRED_ACTIONS`; `MIN_EXTENSION_VERSION` | | `web/src/composables/useSyntheticsRecorder.ts` | `startRecordingFrom`, `hasCapability`, `pickedSelector`, `extensionOutdated` | | `web/src/components/synthetics/journey/{BrowserJourney,JourneySteps}.vue` | per-step record action and its wiring | `click_count` is capped at 3: the recorder only ever emits 1 or 2, and an unbounded count is a way to hold a page's event loop open. The two click fields cross from camelCase to snake_case in `buildV2Step` and nowhere else — reading `step.wire` directly inside it would have worked and invented a second path into storage. ### Depends on a recorder extension build `hover`, the click fields and the capability handshake all need the matching extension build. O2 degrades honestly without it: `hasCapability()` falls back to the pre-handshake set, and an older build raises the outdated-extension warning instead of failing on a message shape it does not recognise. ## Tests - **Rust** — hover accepted as an element action; `button`/`click_count` validated at both bounds; a step carrying neither still validates (the compatibility guarantee). Two existing tests encoded "hover is rejected" and now say the opposite. 101 pass. - **Probe** — hover hovers rather than clicks; a right click sends the recorded button; a double click sends two clicks; a journey stored before these fields replays unchanged. The action union is asserted against the Rust vocabulary, so the next divergence fails a test instead of reaching an executor with no case for it. Also pinned: a selector carrying a frame hop resolves into the iframe, which had no coverage anywhere. - **Web** — 1213 across 60 files. Nine existing tests encoded "hover is retired" across constants, `buildV2Steps`, `buildPayload` and the save-gate schema; each now states the opposite deliberately. - **Extension** — the unmapped-action throw, hover round-tripping both directions, and a double click surviving the round trip as two clicks. `vue-tsc`, `cargo clippy -D warnings`, and `prettier --check` are clean. The last commit is formatting only: the three record-from-step files arrived failing `format:check`, which is a gate of its own and would not have been caught by lint. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
62528b4c12 |
fix(synthetics): sequential recorder setup checklist with state-safe refresh and incognito failure recovery (#13684)
## Summary Follow-up to #13658 — redesigns the recorder setup flow as a sequential-gated checklist and closes the UX holes around refresh, stale connections, and incognito failures. ### Sequential-gated setup checklist (shared by the create-page setup phase and the journey dialog) - Only one task is actionable at a time; later tasks render locked, done tasks collapse to a green check row. - **Task 1 (install)**: Web Store button + an "I've added it to Chrome" attestation (the install happens in another tab the page can't observe). Live bridge detection auto-completes it ("Detected automatically"); checkbox-only completion offers Undo. - **Task 2 (incognito)**: "Do this in Chrome" callout with inline Chrome-UI icons + first-person attestation, collapsing to "Allowed in Incognito" with Undo. - **Task 3 (connect)**: completes only on the real probe signal — attestations can't skip into a recording that would hang. Icon-click is the primary instruction (injects without reloading); refresh is the secondary link. - Journey dialog: per-action subtitle, "n of 3 done" badge, full-width CTA reading "<action> — finish the tasks above first" while locked, a hint naming the exact blocking task, skip link (record only). - Attestations are session-only by design — persisting them would keep tasks pre-completed after the extension is removed. ### State-safe refresh + gate bypass - Entering the setup phase mirrors url/name into the query (`setup=1`); mount restores them, so a mid-setup F5 returns to the checklist with fields intact. - The checklist's "refresh this page" strips the setup flag; when url+name are present and the warm probe detects the extension, the gate auto-commits straight into the editor (recording stays a deliberate click). `?url=&name=` deep links work as a byproduct. ### Incognito failure recovery - Both the replay preflight classification and the recording-start refusal (the extension's raw "Recording needs incognito access…" message) now revoke the disproved attestation and auto-open the setup dialog on its incognito task, with the failed action as the CTA. The warning card slims to Retry / Dismiss / Show setup steps (its chrome://extensions walkthrough duplicated the checklist, and `window.open("chrome://…")` is blocked by Chrome anyway). ### Compulsory re-verification after the incognito toggle - Toggling "Allow in Incognito" **reloads the extension and orphans the tab's bridge** (per the takeover-handshake contract in the extension's content script), so giving the ack invalidates `extensionReady` and re-probes — the connect task stays open until a fresh probe passes. The install fact is latched first so task 1 doesn't regress. ## Test plan - 141 tests across the four specs: ExtensionSetupChecklist 18, ExtensionSetupDialog 19, BrowserJourney 60, CreateBrowserTest 44 — including the deferred-probe assertions that the CTA follows the *fresh* probe verdict, not stale state - `npm run lint` / `npm run type-check` / `npm run lint:design:strict` clean - Manual: full install → incognito → connect flow against the published extension, both failure paths (record + replay without incognito), refresh at each task |
||
|
|
d171d98873 |
fix(synthetics): recorder extension install link, record/replay setup gate, configurable store URL (#13658)
## Summary The OpenObserve Recorder Chrome extension is now published on the Chrome Web Store. This PR wires the browser-test UI to it: - **Install link + setup checklist** — the CreateBrowserTest gate links to the Web Store listing and walks through install → Allow-in-Incognito → connect, with the connect step verified live via the extension probe. The checklist is extracted into a shared `ExtensionSetupChecklist` component. - **Record/replay setup dialog** — `BrowserJourney.vue` now gates both Record and Replay behind an `ExtensionSetupDialog` when the extension is not detected (previously Replay was ungated and would hang in "running" until the 15-min watchdog). - **Loader on Record journey** — the gate's Record button shows a spinner while the extension probe awaits its ~4.5s worst-case timeout. - **Configurable store URL** — the Web Store URL is served by `/config` as `synthetics_recorder_extension_url`, sourced from the new env var `O2_SYNTHETICS_RECORDER_EXTENSION_URL`. The frontend falls back to the built-in constant when the field is absent or empty, so the UI works against older backends and OSS builds. ## Test plan - `ExtensionSetupChecklist.spec.ts` (8), `ExtensionSetupDialog.spec.ts` (11), `BrowserJourney.spec.ts` dialog gating tests — all passing - `npm run lint` / `npm run type-check` clean (3 pre-existing `eslint.config.js` duplicate-key errors untouched) - Manual: record + replay gating verified against the published extension --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
3285a31e6f |
fix: i18n lint enforcement (#13439)
Co-authored-by: Kirtan Thakkar <kirtan@kiara.tech> |
||
|
|
bbed40d8f4 |
feat(synthetics): author-owned locators, and step-scoped run evidence (#13563)
## Summary
Three synthetics workstreams on one branch: author-owned locators (Phase
2b), retirement of version-1 monitors (Phase 2c), and making a failed
browser step diagnosable without leaving the Steps tab.
Everything else in the synthetics suite passes (422 tests across the 21
suites the evidence work touches).
## Author-owned locators (Phase 2b)
The recorder proposes a locator bundle; the author owns its order.
Schema, combined-locator build/read, provenance pinned across the
recorder bridge, and the payload contract tested from both sides.
`337911158d` `e63f8f429f` `50b811a865` `2a978b9408` `c8c081c3c5`
`35ef1c36cb`
## Version-1 retirement (Phase 2c)
Stop creating v1 monitors, delete the v1 migration path and its step
fields, drop `steps_version` from the schema.
`b58b03077d` `75984ad222` `68a33e885d` `a2bffae7b7`
## Run detail — evidence, scoped to the step
Implements §5.3 of `docs/synthetics/step-failure-evidence-design.md`
("render the bundle, scoped to the step"), which was specified and never
built: only the kind-grouped run-level Evidence tab shipped.
**Per-step page activity.** The expanded step now shows the
`evidence.ndjson` events attributed to it — severity-ranked, capped at
5, with "View all N →" deep-linking into the Evidence tab pre-filtered
to that step. One shared `OTable` wrapper renders rows for both surfaces
so they cannot drift, and one composable fetches the bundle once for
both.
`a483796d57` `a7cbe0a3e0` `f63973285e` `eb7ec4f3e6` `1ed226febe`
`e3d969bcb2`
**Settle signals were attributed to the wrong step.**
`failure_detail.settle_signals` accumulates across the whole journey. On
live run `3HFCZ3fm` it held 13 signals — one from step 2, six from step
8, two from step 14 — while the failed step 15 owned none of them, and
the panel rendered all 13 under step 15. The signal that mattered
(`stale POST **/_search_stream, 30274ms`) belongs to step 14, which the
run's own error string says, and step 14 displayed nothing.
`last_attempt_steps[i].settle_signals` had carried correct per-step
attribution all along and was read by nothing.
`6ba6f8d633`
**Artifact URLs carried no origin.** `artifactUrl()` returned a bare
path while every other call in that service goes through `http()` with
`baseURL: store.state.API_ENDPOINT`. Artifact URLs go to `<img src>` and
`fetch()` directly, so in dev they resolved against Vite on `:8081`,
which has no `/api` route and no proxy — every screenshot and evidence
bundle 404'd. Verified against a running backend with a real key:
`:8081` → 404, `:5080` → 200. Production, served from the API's own
origin, is unchanged.
`baa7407cb5`
**The locator ladder was invisible.** `candidates_tried` lists only the
rungs the probe stood on, so a step that matched on its primary looked
identical to a step that had no second candidate — both one row, both a
grey `used_as_primary` badge. On live run `3HGDMrlU` the failing assert
had one authored locator and every `assert`/`fill` step in that journey
is built the same way, while `click` steps average 2.4 candidates. The
section now leads with "N of M tried", names a one-rung ladder as having
no fallback, labels outcomes in words instead of enum values, and dims
unreached rungs the way the timeline dims a skipped step.
`c05e1ce133`
## Test plan
- `npx vitest run src/views/synthetics src/components/synthetics/results
src/components/synthetics/StepEvidence.spec.ts
src/composables/synthetics src/composables/useSyntheticEvidence.spec.ts
src/services/synthetics.spec.ts` → 422 passing
- `npm run type-check` → clean
- `npm run lint:design:strict` → 2 pre-existing regressions above (see
Known failing)
- Behaviour on the run-detail changes was verified against live records
from `OpenObserve Sys Query` and `OpenObserve Cloud Happy Path` rather
than fixtures alone
## Not covered
- The "Add a fallback locator" action from the locator-ladder work needs
a step-level deep link; `synthetics/edit/:id` has no step anchor, so the
warning states the finding without an action.
- Browser-level confirmation of the artifact-URL and locator-ladder
changes is outstanding — the local backend's search service was
returning `tcp connect error` during verification, so those two were
confirmed against records and by unit test rather than in a running
page.
|
||
|
|
db2f0fb62a |
feat(synthetics): attempts view, evidence panel, alerting, concurrency (#13543)
> Note: this branch carries ~20 earlier synthetics commits. The alerting piece is ~280 lines and is cleanly separable if a smaller review is wanted. ## Backend — alert state - **Four columns on `synthetics`** (`consecutive_failures`, `last_alert_at`, `alerting`, `degraded_notified_at`), all defaulted so no backfill is needed - **`DB_SCHEMA_VERSION` 55 → 56** — without the bump the migrator short-circuits and the columns never appear - Guarded with `has_column` on **both** `up` and `down`: SQLite ignores `IF NOT EXISTS` on `ADD COLUMN`, and sea-query has no `drop_column_if_exists` - **Compare-and-swap** accessor (`update_alert_state_if`), because the caller does a read-modify-write with no transaction - `alerting` is a separate column because without it "recovered" cannot be told from "was never alerting" - **`synthetics_jobs::failing_locations`** — the notification previously had no location field, so a six-location check with one broken region could only say "the check is failing" - Distinct subject, headline, icon and colour for FLAKY vs DEGRADED, from one shared `locations_line` helper so Slack/plain-text/email cannot drift > The table is `synthetics`, not `synthetics_monitors` — the entity module is named after the concept but declares `table_name = "synthetics"`. Recorded at the `DeriveIden` so the next column addition doesn't repeat it. ## Performance — the step-stats panel fetched ~35 MB per load - **`recorded_steps` out of the 5000-row tally** — ~60% of payload; ~4 KB/row and near-identical within a config version, so an *aggregation* re-read the same definitions 5000 times. Still written to every record, because steps are editable and history must not be rewritten - **`retry_history` out too**, replaced by `retry_step_ids` scanned only over rows that actually retried - **Key step stats by `step_id`, not name** — a rename *split* one step into two rows; two steps sharing a name *merged* into one - **Single-pass sparklines** — was O(steps²) per row: ~2M iterations for a 20-step journey, ~50M for a 100-step one - **Flaky Rate could exceed 100%** — the fallback incremented the numerator without the denominator - **Label the real window** — a 1-min check × 2 locations × 4 device combos is 11,520 executions/day, so a 5000-row cap is ~10 hours of a "last 7 days" selection ## UI - **Attempts selector** in the run detail — costs no request, `retry_history` is already on the row. Labels are 1-based while `attempt` is 0-based - Each attempt resolves **its own** screenshots, trace and evidence bundle; a superseded attempt's live under an `attempt-N-` key - **Evidence panel** — parses `evidence.ndjson` per line, grouped by kind in severity order, chips with counts visible at zero, third-party dimmed not dropped, truncation stated, four distinct empty states - **Flaky / Degraded / Unstable tiles.** Unstable is partitioned by `(location, device, engine)` — aggregated, a check solidly broken in one region and healthy in five is indistinguishable from one intermittently broken everywhere. It measures *oscillation*, not badness - All flakiness tiles read **"—" at `retries = 0`**, never `0.0%`: a zero is a measurement, that is the absence of one - **`init_ms` and queue delay shown separately** — init was observed at 113,131 ms on a cold Lambda against a 243 ms check; unsubtracted, Lambda locations look permanently slower at every percentile - Steps and Evidence are sibling `OTabPanel`s — stacking them broke the drawer's scroll ## Bugs fixed during review - **`mapRetryHistory` guarded on `Array.isArray`** but the search API returns blob columns as JSON *strings*, so it returned `[]` for every real record — the attempts strip could never render, whatever the query selected. Same bug in `mapEvidence` and the `attempts` fallback - **`mapRunDetail` read `rawHit.attempt`**; the field is `attempts`. The count was 0 on every run - **`mapRetryHistory` hard-coded `status: "failed"`** — reported a flaky run's *passing* final attempt as a failure - **A superseded attempt's failing step rendered as a pass** — the compact timeline's `passed`/`failed` was never normalised to the `ok`/`fail` vocabulary every consumer tests for - **`failure_detail` is not a column** — OpenObserve flattens nested objects; naming the object is rejected by the search API - **The retry-attribution query named `status_reason` unconditionally.** That field only exists once something has been a `warning`, and the three step queries share a `Promise.all` — so one missing column emptied the *entire* Steps tab - **`fetchSchemaFields` returned an empty Set on failure**, which the gate reads as "the schema has no fields", silently degrading every optional column to a literal ## Lease correctness (added after review of the concurrency docs) Two corruption-class bugs, both of which double-count the alert failure streak this PR introduces. Included here rather than in the concurrency branch because they undermine *this* PR's own feature. - **The browser lease validation was per-device while the work is per-job.** `validate_browser_config` computed `(retries+1) x journey_budget + retries x wait` against the 900s lease, but the probe runs `browser_devices` **sequentially inside** the leased job and nothing multiplied by the combo count (`MAX_BROWSER_DEVICE_COMBOS = 12`). At defaults a plain **desktop + mobile** config is 1210s of work; validation computed 605s and allowed it. It then blew its 900s lease on **every run, forever**, with nothing failing at save. At the cap: 7260s vs 900s. The consequence is verbatim what the `LEASE_SECS` comment in `dispatcher/mod.rs` was written to prevent — *"the reaper would requeue mid-run and the journey would EXECUTE AGAIN — duplicate result records, multiplied browser cost, and false alerts caused by the reliability fix itself."* All three happen at two devices today, on the **managed** path, since browser is Lambda-only. > ⚠️ **Breaking validation change.** An existing 2+ device check will fail to save until its budget, retries or combo count comes down. The error now names the combo count as a lever. **Query dev and prod for `json_array_length(config->'browser_devices') > 1` before rolling out.** - **`ack_complete` had no status guard** — `WHERE id = $4` alone. A duplicate ack succeeded and the caller called `increment_jobs_done` again for one job: `jobs_done` overshot `job_count`, the run was declared complete on a **partial set**, and since this PR it also advanced `consecutive_failures` twice, so `alert_if_fails: 3` fires after two failures. Reachable today with no concurrency work: `aws-sdk-lambda` retries a timed-out `RequestResponse` invoke, re-executing a check already in flight. `AND status = 1` makes it idempotent, and `ack_complete` now returns `None` when it did not apply so the caller skips run accounting. Reaper reassignment is covered too, as of the concurrency work merged below: `AND claimed_by = $5`. ## Verification `vue-tsc` + `type-check:app` clean · Prettier + design ratchet clean · **711 synthetics tests** · `cargo check` clean · infra unit tests pass. Migration applied against a real SQLite metastore: `55 → 56`, all columns correct. Every drawer field verified against live ingested data. > `MonitorResults.spec.ts` fails on a pre-existing `storage.ts` import error — identical on a stashed tree. ## Requires o2-enterprise#2305 — the `AlertDecision` this consumes. Merge together; each is inert alone. --- # Also merged: probe concurrency (#13552) The concurrency branch merged into this one, so this PR now carries both. Everything below is a correctness fix — none of it is throughput work. ### The reaper never completed a run, on any path A run completes when `jobs_done` reaches `job_count`, and only three callers move that counter: the probe ack, the dispatcher's failed invoke, and the reaper. The reaper never did — including in `dead_letter_expired`, whose whole purpose is to report "we gave up after N attempts". It wrote a customer-visible error record into a run that then stayed open forever: no `completed_at`, and since this PR's alerting work, no `resolve_alert` either, so the failure streak never moved. The mechanism was `requeue_expired` ignoring `valid_until`. It reset a job to Pending, and `prune_stale` — later in the **same tick** — deleted it again, because `valid_until` is one interval (60s for a 1-minute check) while a lease is 300s+. `dispatch_attempts` never got past 1, so `MAX_DISPATCH_ATTEMPTS` was unreachable and the retry budget was dead code on the agent path. - requeue only while the job is still inside its window - dead-letter everything that can no longer report, tagged with why (attempts exhausted / window closed / never dispatched), so a dead agent does not read as an unresponsive probe - per-row compare-and-swap instead of SELECT-then-bulk-UPDATE; the reaper runs on every alert_manager node - increment **before** the ingest-token lookup, which returns early when an org has no token ### Every check's retry sequence is bounded by the lease Retries run *inside* the leased job. The browser path has checked this since `journey_budget_ms`; the protocol path never did, and its inputs were unbounded — the `5_000..=300_000` bound on `timeout_ms` is **browser-only**, so a TCP check with `timeout_ms: 3_600_000` saved fine. With the reaper now completing runs, the symptom is a wrong answer rather than a stuck one: the lease expires mid-flight, the reaper completes the run as Error, and the probe's real ack is rejected as stale. A passing check reports Error permanently. `timeout_ms=100s, retries=2, wait=30` needs 360s and hits it. `lease_batch` treats the client's `lease_secs` as a floor request, not the decision — both probes guess 300s, and a probe cannot know how long its own job may take. ### Guards on the ack, and on dispatch failure `AND claimed_by = $5` closes reaper reassignment. `claimed_by` is `Option` during rollout: an older probe acks without it and falls back to the status guard, so nothing is discarded. `fail_dispatch` had no status guard, so a dispatch judged failed *after* the probe acked reset a **completed** job to Pending — leased again, run again, duplicate result, `increment_jobs_done` twice. Third outcome `AlreadySettled` added; the dispatcher matches all three with no wildcard, so handling it is compile-time enforced. `limit` is now clamped before the query. It is cast to `u64`, where a negative wraps to ~1.8e19 and the LIMIT goes unbounded — one agent leasing the entire pending queue for its pool. Reachable from one mistyped env var. ### Queue backlog is observable `synthetics_pending_jobs` and `synthetics_oldest_pending_age_seconds`, per location and pool. `started_ts - scheduled_ts` already covered work that *ran*; a check nobody leased produces no record, so its backlog was invisible by construction. ## Before merging this to main The `timeout_ms` validation is a **breaking change for existing protocol configs**. It runs at create/update only, so nothing stops on deploy — but an over-budget check is rejected the next time someone edits it. Expected result is zero rows: `retries` of 0 or 1 cannot trip the budget rule at all, and the defaults sit at 10,000ms, 1.1% of the lease. ```sql WITH c AS ( SELECT id, org_id, name, synthetics_type, COALESCE((config->>'timeout_ms')::bigint, 10000) AS t, COALESCE((settings->>'retries')::bigint, 0) AS r, COALESCE((settings->>'wait_before_retry_secs')::bigint, 5) AS w FROM synthetics WHERE synthetics_type <> 'browser' ) SELECT id, org_id, name, t AS timeout_ms, r AS retries, w AS wait_s, (r + 1) * t + r * w * 1000 AS worst_case_ms FROM c WHERE t NOT BETWEEN 1000 AND 300000 OR (r + 1) * t + r * w * 1000 > 900000 ORDER BY worst_case_ms DESC; ``` Anything returned is a check that **cannot work today either** — fix the config rather than loosening the rule. ## Not done Wiring the reaper's now-completing runs to a **notification**. The send lives in a crate that depends on `o2_enterprise`, so the reaper cannot call up into it; it needs the send moved into `openobserve_core::synthetics` or a queue. No regression — before this, the run never completed, so there was no notification either. --------- Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: omkark06 <omkar@zinclabs.io> Co-authored-by: Harsh Mahajan <115500013+007harshmahajan@users.noreply.github.com> Co-authored-by: Yashodhan Joshi <yashodhan@openobserve.ai> Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai> Co-authored-by: Shrinath Rao <shnath@openobserve.ai> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
5ec9b89ff8 |
build: FE code format check for improved maintainability (#13351)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
f15e27e5fd |
refactor: design token migration + CI guards (#13173)
# Design System Unification — one visual language, enforced end-to-end
Establishes **one source of truth for every visual decision**, wires the
whole app to it, and **locks it in with CI** so it can't drift back.
### Foundations
- **Design-token system ("one knob per decision").** Every colour, text
size, spacing, corner radius, and shadow is a named token defined in
exactly one place — change the token, every screen updates. Collapsed
hundreds of near-duplicate definitions and removed "fake" duplicates
that pretended to be different but weren't.
- **Shared component library (O2).** Buttons, tables, dialogs, drawers,
form fields, badges, etc. already know the correct colours, spacing, and
dark-mode behaviour; new screens compose them instead of hand-styling.
Added new primitives on this branch (`OContent`, `KpiCard`) and
standardized existing ones.
- **One page structure everywhere** (`PageLayout` / `AppPageHeader` /
`AppPage` / `OContent`) — titles, breadcrumbs, spacing, and content
edges line up identically across every screen.
- **One table implementation** — all tabular data uses the same table
(sorting, density, sticky headers, empty states).
- **Styling consolidated onto Tailwind; old systems removed** —
hand-written CSS driven to the practical minimum, the legacy **Quasar**
framework fully removed, surviving stylesheets required to justify
themselves.
- **Two-tier corner radius** — a tight **4px** for controls and a soft
**12px** for surfaces (dialogs, cards, the app shell), plus a
full-circle option — replacing five radius names that all secretly meant
the same thing.
### Detailed improvements across screens
**Page structure & alignment** — unified page shell rolled across ~40+
screens (IAM, Settings, Alerts, Dashboards, Functions, Pipelines, RUM,
Metrics, Synthetics, Billing, editors, lists); one header height; one
page-edge grid driving headers, tables, rails, and tabs; unified
side-rail widths; inset rail selection/hover pills; every tab strip on
the grid line; tightened title/subtitle spacing.
**Tables (cross-screen)** — action columns consistently centered (incl.
Organizations); unified row-number column with no "#" truncation;
non-standard tables restyled to match; loading skeletons made
geometrically identical to the loaded table; symmetric edge inset; IAM
first-column grid alignment fixed.
**Traces** — flame graph + span-detail correlation panel fixes;
correlated logs/metrics placeholder fit; sticky headers; removed a
double scrollbar + a 1px sliver; aligned table fonts/badges; polished
the service detail drawer; stream-selector + correlation alignment;
aligned loading spinners; floating overlay arrows for the
disabled-services strip.
**Logs** — field-list controls aligned (focus ring no longer clipped);
detail-drawer spacing + metrics-tab overflow fixed; Run Query toolbar
tidied; listing sizing + stray border fixed.
**Metrics** — search added to the "Type" facet rail and aligned with the
other rails; proper empty states for the explorer and facet rail.
**Dashboards** — removed inconsistent card shadows; tightened
borders/resizers/field-list spacing; aligned View Dashboard chrome to
the grid; chart colours via the token helper.
**Home** — redesigned the Usage tab; added reusable KPI stat cards so
summary strips stop drifting.
**Dark mode** — new theme-switch animation; fixed a 1px content shift on
toggle and a white flash on load; fixed AI-chat text and assorted
light/dark mismatches; completed the token-driven dark migration.
**Empty states, controls & small polish** — restored 3 broken
empty-state animations; adopted the standard empty state; added the
sliding indicator to the toggle control; fixed the Quality-page inset +
drawer badge; refreshed Search History / Schedulers; fixed the
alert-history drawer scrollbar + timeline hover; removed a stray
menu-bar border.
### Dead code & cruft removal
- **Deleted the entire legacy `utilities.css`** global stylesheet (well
over a thousand lines) — evacuated in waves, roughly half of it dead
once traced.
- **Removed Quasar entirely**, including dead `.q-*` styles and ~25
phantom `--q-*` variables that were silently breaking bits of the UI.
- Stripped hundreds of **dead CSS classes and tokens that compiled to
nothing** — e.g. 46 uses of a colour class with no backing token, a
no-op shadow class on 51 elements, dead layout/utility classes, a
leftover `card-container` block, a dead table-actions token, and a
mis-registered gradient that rendered nothing.
- Cut **unused keyframe animations (19 → 3)** and removed **unused
components** + a stray build artifact.
- Net effect: a much smaller, leaner styling surface — less to maintain,
fewer dead ends to copy.
## Safety & verification
Large but low-risk: this is overwhelmingly a **styling and structure**
change, not product behaviour or data. Guarded by the
design-token/consistency/type checks above plus the existing test suite,
and reviewed screen-by-screen.
---------
Co-authored-by: Kirtan Thakkar <kirtan@kiara.tech>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: ktx-mihir <mihir.patel@kiara.tech>
|
||
|
|
9063b4c943 |
fix: add check type picker before builder (#13248)
## What changed Adds a `CheckTypePicker` component that presents 5 check types (Browser, HTTP, TCP, TLS, SSH) as action cards before the builder flow. Updates `OEmptyState` with a `columns` prop and `:filtered` state for contextual empty messaging. Adds `hideChevron` support to `EmptyStateActionCard` for inline variants. The empty state in `MonitorTable` now passes `:filtered` and `columns` to `OEmptyState`. ## Why Synthetic monitoring needs a type-selection step between the listing page and the check builder. Previously, the empty state was a static custom inline block; now it respects active search/filter state via the `:filtered` convention and uses the same `OEmptyStateActionCard` component as the type picker. --------- Co-authored-by: Claude <claude@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
4031f76426 |
feat: synthetic monitoring (#12849)
Design at : https://github.com/openobserve/designs/tree/main/synthetics ref: https://github.com/openobserve/o2-enterprise/issues/2095 --------- Co-authored-by: omkark06 <omkar@zinclabs.io> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Claude <claude@users.noreply.github.com> |
||
|
|
cb06f07118 | fix: logs menu item pin option & theme related minor fixes (#12964) | ||
|
|
45793bf76c |
fix: persist theme selection by name with redesigned theme drawer (#12890)
Theme selection across light and dark modes is now persisted by name instead of numeric ID. A shared registry (constants/themes.ts) owns the single source of truth for all predefined theme definitions, and utils/themeManager.ts provides a central applyCurrentTheme() / applyThemeForMode() API that replaces scattered inline resolution logic in App.vue and PredefinedThemes.vue. Custom themes continue to store their hex color as the source of truth, marked with the CUSTOM_THEME_NAME sentinel. The theme drawer is redesigned: a segmented Light/Dark toggle replaces the tabs, each theme is a single clickable row (no per-row Apply button), the applied theme is highlighted with a primary ring plus an Applied badge, long names truncate instead of wrapping, and the custom color row opens the picker with an Apply/Cancel dialog. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
b948361769 |
chore: update copyright year to 2026 (#11166)
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com> |
||
|
|
2cd84ff77b | fix: Load pricing from json (#10857) | ||
|
|
83e1edc06d |
fix: 10159 replace dashboard panel with custom component in correlation logs tab v1 (#10246)
### **PR Type** Enhancement, Tests ___ ### **Description** - Introduce `useCorrelatedLogs` composable for streaming correlated logs - SQL builder with semantic field mapping and request cancellation - Caching of semantic patterns and dynamic filter management - Add `TimeRangeEditor.vue` and `DimensionFilterEditor.vue` UIs - Preset and custom time window selection - Stable/unstable dimension filter editing with wildcard toggle - Extend cell actions to respect `hideSearchTermActions` flag - Add comprehensive unit tests for new composables and components ___ ### Diagram Walkthrough ```mermaid flowchart LR A["useCorrelatedLogs\n(composable)"] -- "provides state & methods" --> B["CorrelatedLogsTable.vue\n(table UI)"] B -- "opens filter editor" --> C["DimensionFilterEditor.vue\n(filter UI)"] B -- "opens time editor" --> D["TimeRangeEditor.vue\n(time UI)"] A -- "used by" --> E["CellActions.vue\n(hide search term)"] ``` <details> <summary><h3> File Walkthrough</h3></summary> <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>3 files</summary><table> <tr> <td><strong>useCorrelatedLogs.ts</strong><dd><code>Add correlated logs composable with streaming API</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-310992fb4914c6eaffbbce225e0c0683c2edad2bb0ab0f8e43530fc38152ed2a">+583/-0</a> </td> </tr> <tr> <td><strong>TimeRangeEditor.vue</strong><dd><code>Add time range editor dialog component</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-fbebc998fca2093c7f168d13e720aa6606b21ace2e9f2185f81c49e59e9eec70">+498/-0</a> </td> </tr> <tr> <td><strong>DimensionFilterEditor.vue</strong><dd><code>Add dimension filter editor dialog component</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-6c9172f6882b50f84b5927c491c21702617c66ddde648170199bb11b360f4dde">+324/-0</a> </td> </tr> </table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>useCorrelatedLogs.spec.ts</strong><dd><code>Add unit tests for correlated logs composable</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-f5ec3243549ef3a5081acfb9b928fb87d26e86e04a669a85ad03a1a053ec4eac">+591/-0</a> </td> </tr> </table></details></td></tr><tr><td><strong>Bug fix</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>CellActions.vue</strong><dd><code>Respect hideSearchTermActions in cell actions</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-de54e5b8cd9503c53f3f802ac7bc7e3d25846f1657c77cd99534d9f60673992e">+6/-2</a> </td> </tr> </table></details></td></tr><tr><td><strong>Refactoring</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>useLogsHighlighter.ts</strong><dd><code>Move cache inside hook and format regex</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-ad7744a2edc4764be1c7d67feb7fe1473536af245821898a9136256b3aeb0342">+8/-3</a> </td> </tr> </table></details></td></tr><tr><td><strong>Additional files</strong></td><td><details><summary>20 files</summary><table> <tr> <td><strong>features.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-f3c3ea1b3f6e34a0718bced5c01c09bfe13b5ba7936ee8b77eb66b8c14767d49">+18/-0</a> </td> </tr> <tr> <td><strong>de.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-78f24ecb2dbcfc38fdf3ec22b2559a5b40d236ea689d1c55f5d3e87168310264">+65/-4</a> </td> </tr> <tr> <td><strong>en.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-892aa3d75ab6e129ef9116aa21bec1b9a15ba69ce5366d2a19128078c690d824">+64/-1</a> </td> </tr> <tr> <td><strong>es.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-ac2a2167b8b973e3f776f9fe3b43bef4576470d8ad33f3d7cfaff6edff0e5778">+65/-4</a> </td> </tr> <tr> <td><strong>fr.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-db80e762b88ddf183820c050cdc6b215e6b02b365b5e73f5152af46b0d26f1a2">+65/-4</a> </td> </tr> <tr> <td><strong>it.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-2de78074a5f887afddce60d694ead9322e6ab223eb70251c13819f3028bdc70d">+65/-4</a> </td> </tr> <tr> <td><strong>ja.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-092e49c5f9fbc1b539ab9c2866d108d0ce1d314022b4c294eb4611b285e7bbd3">+65/-4</a> </td> </tr> <tr> <td><strong>ko.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-50e27ca1b4825a5026f3a251bfcf79c97cab07cfade2ebd512d332453d707c48">+65/-4</a> </td> </tr> <tr> <td><strong>nl.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-a1706021687ae5d8a1c006c49eab3946174fecd895f9b70a89c2e76d97250906">+65/-4</a> </td> </tr> <tr> <td><strong>pt.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-38e804f64cb5e0e451849fc84e9b46e53c954a4a4263d51c18665ad45f4b4815">+65/-4</a> </td> </tr> <tr> <td><strong>tr.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-6f0f131e9e2591480c4c5d1eaffc72d02dc31cbd8d3f90d8f012f08cabac8818">+65/-4</a> </td> </tr> <tr> <td><strong>zh.json</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-8818055db58f83230aeea4ebfd4cec31d924e8c47b6f91298e356959ab25339e">+65/-4</a> </td> </tr> <tr> <td><strong>CorrelatedLogsTable.spec.ts</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-2cbeccd1d13276ca572faf566cbfef3adb2a54fa65d8197ade08dd8414464293">+514/-0</a> </td> </tr> <tr> <td><strong>CorrelatedLogsTable.vue</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-57e0ec3ac2762de21e67254edf83a4559490f717a8826762c0566fa3b70b6fb8">+978/-0</a> </td> </tr> <tr> <td><strong>DimensionFilterEditor.spec.ts</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-94cbaad5e0f29d5cb695077c9b7915cfee73e0b510b87503660407ce349848cb">+581/-0</a> </td> </tr> <tr> <td><strong>DimensionFiltersBar.spec.ts</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-852ddb2775c9f58605e39ff8aa8b6a22ae07a8330b9acf9d22535dd49f3f0ea4">+356/-0</a> </td> </tr> <tr> <td><strong>DimensionFiltersBar.vue</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-6199755ef4f3b11c06759aabe761173fe475a21daefb0a3e503c9b31b934f257">+155/-0</a> </td> </tr> <tr> <td><strong>TelemetryCorrelationDashboard.vue</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-b77a766fa0094f641873071a8f13c73704933b941f387ed105e85a4e59efdb38">+901/-477</a></td> </tr> <tr> <td><strong>DetailTable.vue</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-80552b5d25fa6cef9fbbe430b1865d761c4b132284c2d2175afceea8cbabc8c7">+88/-2</a> </td> </tr> <tr> <td><strong>TenstackTable.vue</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/10246/files#diff-bc3c669f5ab65a42ae378df1f7d6b35014c9c220790bdcc72b47f55d1385dc22">+48/-0</a> </td> </tr> </table></details></td></tr></tr></tbody></table> </details> ___ --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: omkark06 <omkar@zinclabs.io> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> |
||
|
|
576671d14f |
fix: automate update process of feature master list on about us page (#10010)
### **PR Type** Enhancement ___ ### **Description** - Centralize features in JSON registry - Refactor ComparisonTable to load from registry - Add GitHub Action for auto-updating features.json - Update Slack PR notification configuration - Enable JSON module imports in tsconfig ___ ### Diagram Walkthrough ```mermaid flowchart LR PRDesc["PR description feature section"] AutoUpdate["Auto-update features.json Workflow"] featuresJSON["features.json"] featuresTS["features.ts registry"] TableComp["FeatureComparisonTable.vue"] PRDesc -- "triggers" --> AutoUpdate AutoUpdate -- "updates" --> featuresJSON featuresJSON -- "loaded by" --> featuresTS featuresTS -- "used by" --> TableComp ``` <details> <summary><h3> File Walkthrough</h3></summary> <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>features.ts</strong><dd><code>Add central feature registry and helper functions</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-232fb84d995004ab5e3da68e3a9fc835808f460feb9f4478dca50ea4a48ed057">+104/-0</a> </td> </tr> <tr> <td><strong>FeatureComparisonTable.vue</strong><dd><code>Refactor table to load features from registry</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-450bc4b412ffde37d04f96046199090e3d41face1ee85b32e446c9b470ce299e">+31/-30</a> </td> </tr> </table></details></td></tr><tr><td><strong>Configuration changes</strong></td><td><details><summary>6 files</summary><table> <tr> <td><strong>auto-update-features.yml</strong><dd><code>Add workflow to auto-update features.json</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-7179e615740ebfe7a08143d567c20bdf7d813506f77c6efba463d105b48379ad">+253/-0</a> </td> </tr> <tr> <td><strong>pr-slack.yml</strong><dd><code>Update Slack action with new webhook syntax</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-c049020d06d481f16942b242608c22fa8377924730787f97288e03561768f51a">+3/-3</a> </td> </tr> <tr> <td><strong>features.json</strong><dd><code>Add JSON-based features configuration</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-f3c3ea1b3f6e34a0718bced5c01c09bfe13b5ba7936ee8b77eb66b8c14767d49">+262/-0</a> </td> </tr> <tr> <td><strong>features.schema.json</strong><dd><code>Add JSON schema for features.json validation</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-42009a609f9d2eb5a6a7264d7c236ef538fd624f29edf02759bd3b231453be27">+71/-0</a> </td> </tr> <tr> <td><strong>tsconfig.app.json</strong><dd><code>Enable JSON module imports in app config</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-1fc2dc23685a64f037b0063bf18fc420a8faeb83e98a2cc2b407f1a25c4fc1f5">+1/-0</a> </td> </tr> <tr> <td><strong>tsconfig.json</strong><dd><code>Enable JSON module imports in base tsconfig</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/10010/files#diff-0dafb2d38c20327f4a74c03733790ccca87a4bbda69ec4c03aa362524b0522ca">+1/-0</a> </td> </tr> </table></details></td></tr></tr></tbody></table> </details> ___ |
||
|
|
9444447498 |
fix: Free trial rebase (#6922)
Cherry pick of https://github.com/openobserve/openobserve/pull/6807 after cloud branch was merged into main --------- Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: Bhargav <BJP232004@GMAIL.COM> Co-authored-by: Taiming Liu <liutaiming3@gmail.com> Co-authored-by: Abhay Padamani <141122205+ktx-abhay@users.noreply.github.com> Co-authored-by: Subhra264 <chakrabortysubhradeep556@gmail.com> Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai> |
||
|
+2 |
0d9f47966b |
feat: Organization revamp (#5579)
Fixes #5131 Addresses #5408 ### Revamp - Created a new table to store organizations in the `organizations` table. Earlier, we never stored organizations in any table, rather we used to store the organizations in the meta table as part of the `user` json. - The users and organization membership relations are now moved to its own separate tables - `users` and `org_users`. ### New changes **API changes** - - `/organizations` - `POST` api to create an org and save it in the meta table. In non-enterprise version, currently only the root user can create the org. For enterprise version with rbac enabled, anyone with `CREATE` access for organizations can create the organization and becomes an admin. Root user can always create an organization. - `/{org_id}/rename` - `PUT` api to rename the existing org. Only root user and the admins of the org can access this API. The payload for following APIs are changed - - `POST api/{org_id}/roles` - `{"name":"new_role"}` is changed to `{"role":"new_role"} - `POST api/{org_id}/users/{user}` - `{"role":"viewer","custom_role":["role_name"]}` is the new payload where `custom_role` is optional and is array of custom roles (only works in enterprise with rbac enabled) which will be assigned to the user. The value of `role` can be standard role or as well as any custom role (when it is custom role, the standard role assigned to the user is decided based on the enterprise env variable - `O2_DEX_DEFAULT_ROLE`). - `POST api/{org_id}/users`- the payload - ``` {"email":"user@user.com","role":"viewer","custom_role":["create_org_permission"],"password":"12345678", "first_name": "", "last_name":""} ``` - `PUT api//{org_id}/users/{email_id}` the payload - ``` {"first_name":"Hello","last_name":"j","role":"viewer","isExternal":false,"change_password":false,"password":"","custom_role":["create_org_permission"]} ``` A new ENV variable is introduced - `ZO_CREATE_ORG_THROUGH_INGESTION` (default `false`) which if true, an org will automatically created when ingesting data to a new org. If false, user can not create org by ingesting data to new org, they need to first call the `POST /organizations` API. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes **New Features** - Added a `cloud` feature for enhanced organizational management capabilities. - Introduced new methods for managing organizational users and asynchronous message processing. - Enhanced user invitation and membership features, including improved role handling. - Implemented configurable ingestion URL support across various components. - Added new functionality for user management and organization handling in the super cluster architecture. **Improvements** - Refined user authentication and authorization processes, including error handling. - Updated database schema to support multi-organization architecture. - Enhanced pagination settings and UI components for better user experience. - Improved handling of organization names and user roles in notifications and alerts. - Streamlined service account token management with visibility enhancements. - Enhanced the `AddUpdateOrganization` component with improved user input handling and validation. - Updated the `AppOrganizations` component to dynamically load the appropriate organization management interface. - Improved the `ServiceAccountsList` component with updated pagination options and token handling logic. **Bug Fixes** - Resolved issues with user role assignments and organization management inconsistencies. - Corrected routing and navigation logic for login and logout processes. - Addressed various error handling scenarios in user and organization processes. - Fixed issues with the visibility of service account options in the `EditGroup` and `EditRole` components based on the cloud configuration. **Breaking Changes** - Significant restructuring of user and organization data models. - Changes to authentication workflows and configuration handling. - Removal of certain components related to user and organization management. - Updated the logic for determining the ingestion URL across various components. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: Bhargav <BJP232004@GMAIL.COM> Co-authored-by: Taiming Liu <liutaiming3@gmail.com> Co-authored-by: hengfei yang <hengfei.yang@gmail.com> Co-authored-by: harshiv-7 <harshiv@openobserve.ai> Co-authored-by: Huaijin <haohuaijin@gmail.com> Co-authored-by: Zhao.wei <weizhao029@gmail.com> Co-authored-by: ShyamOOAI <shyam@openobserve.ai> Co-authored-by: oasisk <ashish.j.kolhe@gmail.com> Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai> Co-authored-by: Yashodhan Joshi <yashodhan@openobserve.ai> Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com> |
||
|
|
9ace66ac75 |
chore: rename zinc to OpenObserve (#4807)
rename zinc to OpenObserve --------- Co-authored-by: Taiming Liu <90490946+taimingl@users.noreply.github.com> |
||
|
|
1b3aec6911 |
docs: update license in other missing files (#2062)
update license in other missing files to AGPL |
||
|
|
af521fde54 | fix: update license (#1404) | ||
|
|
59c0b2438e | feat: stripe integration (#938) | ||
|
|
176cb7799e | fix: billing plan changes (#877) | ||
|
|
e62ac76366 |
fix: Billing UI changes (#594)
* fix: billing changes * fix: ui changes for billing * fix: ui changes for billing |
||
|
|
2928fcf08f | fix: billing changes (#591) | ||
|
|
3de53cdbf6 | feat: Metrics explorer UI (#575) | ||
|
|
e7d458e572 |
feat: Issue 435 single UI repo (#510)
* feat: merged mainlayout * structured with composable * fix login flow for single ui repo * merged ui code for user & login module * billing and organization module code merge * feat: final merge single UI repo * refactoring for enterprise code * feat: merged mainlayout * structured with composable * fix login flow for single ui repo * merged ui code for user & login module * billing and organization module code merge * feat: final merge single UI repo * refactoring for enterprise code * feat: removed files * fix: added ext * fix: organization not getting loaded * merge with main |
||
|
|
55c98d1250 | license text (#68) | ||
|
|
147362cb40 | zinc-observe initial commit |