Skip to content

feat: Add Zexbox.OpenTelemetry URL helpers#55

Open
Jez-A wants to merge 10 commits intomasterfrom
open_telemetry_in_zexbox
Open

feat: Add Zexbox.OpenTelemetry URL helpers#55
Jez-A wants to merge 10 commits intomasterfrom
open_telemetry_in_zexbox

Conversation

@Jez-A
Copy link
Contributor

@Jez-A Jez-A commented Mar 9, 2026

Summary

PR: #53 adds the Jira client used to search, create, add comments, and transition issues and tickets. Stacked on this PR.

PR: #54 adds the AdfBuilder which builds Atlassian Document Format (ADF) maps for Jira issue descriptions and comments. Stacked on #53.

PR: #52 adds the public entry point to handling errors (AutoEscalation). Stacked on #54.

The planned merge order is this PR first, then 53, then 54, then 52.

Changes

  • Adds Zexbox.OpenTelemetry: reads the current OTEL span context to produce environment-appropriate observability URLs:
    • Grafana Tempo trace URL (production/sandbox)
    • Local Jaeger trace URL (dev/development)
    • Kibana Discover log URL (production/sandbox), with optional trace ID filter
  • Adds :jason and :opentelemetry_api dependencies
  • All functions return nil gracefully when OTEL is unconfigured or there is no active span

Test plan

  • mix test test/zexbox/open_telemetry_test.exs — 17 tests covering all three public functions across environments, with and without active spans, and on OTEL exception
  • mix test — full suite green

🤖 Generated with Claude Code

Adds OpenTelemetry observability URL helpers that mirror Opsbox::OpenTelemetry.
Provides Grafana Tempo trace URLs, local Jaeger URLs (dev/development), and
Kibana Discover log URLs — all returning nil gracefully when OTEL is unconfigured.

Adds opentelemetry_api ~> 1.4 and jason ~> 1.4 dependencies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Jez-A and others added 4 commits March 9, 2026 14:28
Jaeger is not available locally. generate_trace_url/0 now returns nil for
non-production/sandbox environments instead of a localhost Jaeger URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: Add Zexbox.JiraClient to link error handling with support processes.
@@ -0,0 +1,131 @@
defmodule Zexbox.OpenTelemetry do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still purely additive for now.
The ADF builder here: https://github.com/Intellection/zexbox/pull/54/changes#diff-f51eafc4c4596d3e2ee95a3fef46c8534d5da59ec071d34d01302188ccba021fR12 will make use of these methods to enrich the descriptions/comments of the newly created Jira tickets.

Jez-A and others added 4 commits March 9, 2026 16:25
- Replace ctx != nil && guard with case pattern match in valid_active_span?/0
- Map :undefined -> nil in get_span_ctx/0 so callers pattern match cleanly on nil
- Delegate generate_trace_url/0 and kibana_log_url/0 to private pattern-matched
  functions (build_trace_url/2, build_kibana_url/2), removing duplicated env guards
- Pass ctx explicitly to hex_trace_id/1, removing redundant get_span_ctx/0 calls
- Extract kibana_subdomain/1 and trace_filter/1 as pattern-matched private functions
- Add @grafana_host and @kibana_host module attributes
- Remove :test/:dev fallback clauses from tempo_datasource_uid/0
- Replace @compile_env with :test as safe runtime default in app_env/0
- Simplify with_no_span/1 test helper — :otel_span mock no longer needed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ion signatures

- Rename all ctx variables to context for clarity
- Remove app_env() from build_trace_url/1 and build_kibana_url/1 signatures;
  private functions now call app_env() directly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
"""
@spec generate_trace_url() :: String.t() | nil
def generate_trace_url do
build_trace_url(get_span_context())
Copy link
Contributor Author

@Jez-A Jez-A Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Includes the current trace ID in the query when an active span is present.
"""
@spec kibana_log_url() :: String.t() | nil
def kibana_log_url do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

datasource: uid,
queries: [
%{
refId: "A",
Copy link
Contributor Author

@Jez-A Jez-A Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reusing the same definition than in https://github.com/Intellection/opsbox/blob/master/lib/opsbox/opentelemetry/opentelemetry.rb#L33
There is definitely a concern of effort change if we ever need to update it, but I reckon this is fine at this stage.

app_encoded = URI.encode(service, &URI.char_unreserved?/1)
trace_part = trace_filter(context)

"https://kibana.#{kibana_subdomain(env)}#{@kibana_host}/app/discover#/?_a=(columns:!(log.message),filters:!()," <>
Copy link
Contributor Author

@Jez-A Jez-A Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also imported this url & query from its ruby counterpart

Comment on lines +21 to +24
@production_tempo_uid "een1tos42jnk0d"
@sandbox_tempo_uid "eehwibr22b6kgb"
@grafana_host "zappi.grafana.net"
@kibana_host "zappi.tools"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jez-A we need to keep in mind that this is open-sourced, not a private repo. We can't have any hard coded defaults like this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also worth thinking a bit more holistically about whether Zexbox is the correct place for this. I'd argue no - the package is about observability, and escalation in my mind is way more opinionated and probably falls outside the domain

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants