Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/exporter/otlp/proto/http/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "OpenTelemetryExporterOtlpProtoHttp"
uuid = "f175482f-0544-4037-b362-361efbf21c04"
authors = ["Jun Tian <tianjun.cpp@gmail.com>"]
version = "0.1.6"
version = "0.1.7"

[deps]
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
Expand All @@ -11,7 +11,7 @@ OpenTelemetrySDK = "f5929ecf-be04-446c-b2f2-494e1fe70ee4"
ProtoBuf = "3349acd9-ac6a-5e09-bcdb-63829b23a429"

[compat]
HTTP = "1"
HTTP = "1, 2"
OpenTelemetryAPI = "0.4,0.5"
OpenTelemetryProto = "0.19,0.20"
OpenTelemetrySDK = "0.3,0.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ import OpenTelemetryProto.opentelemetry.proto.metrics.v1 as METRICS
import OpenTelemetryProto.opentelemetry.proto.common.v1 as COMMON
import OpenTelemetryProto.opentelemetry.proto.resource.v1 as RESOURCE

# HTTP.jl 2.0 renamed the request-wide deadline keyword: `readtimeout` (HTTP 1.x)
# became a deprecated alias mapping to the inactivity-based `read_idle_timeout`,
# while overall request deadlines now use `request_timeout`. Detect the major
# version once at load time and pick the right keyword.
#
# Primary signal is the package version. `pkgversion(::Module)` exists since
# Julia 1.9 but may return `nothing` (e.g. when a module wasn't loaded from a
# versioned package), so we fall back to API feature detection: the `HTTP.Servers`
# submodule exists throughout HTTP 1.x and was removed in 2.0, making it a
# reliable discriminator that also covers Julia < 1.9 (where only HTTP 1 can
# resolve, since HTTP 2 requires Julia >= 1.10).
const _HTTP_V2 = let v = isdefined(Base, :pkgversion) ? Base.pkgversion(HTTP) : nothing
v === nothing ? !isdefined(HTTP, :Servers) : v >= v"2"
end

struct OtlpHttpExporter{Req,Resp} <: SDK.AbstractExporter
url::String
headers::Vector{Pair{String,String}}
Expand Down Expand Up @@ -76,14 +91,18 @@ function SDK.export!(x::OtlpHttpExporter{Req,Resp}, batch::Union{AbstractVector,
encode(e, convert(Req, batch))
seekstart(io)

# `retry` / `retry_non_idempotent` remain valid keywords in both HTTP 1.x
# and 2.x; only the timeout keyword changed (see `_HTTP_V2` above).
timeout_kw = _HTTP_V2 ? (; request_timeout = x.timeout) : (; readtimeout = x.timeout)

res = API.with_context(; API.SUPPRESS_INSTRUMENTATION_KEY => true) do
HTTP.post(
x.url,
x.headers;
body = io,
readtimeout=x.timeout,
retry=true,
retry_non_idempotent=true
x.url,
x.headers;
body = io,
retry = true,
retry_non_idempotent = true,
timeout_kw...,
)
end

Expand Down
4 changes: 2 additions & 2 deletions src/exporter/prometheus/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "OpenTelemetryExporterPrometheus"
uuid = "34e26579-e93c-4b5e-ba07-7afb633408c2"
authors = ["Jun Tian <tianjun.cpp@gmail.com>"]
version = "0.3.1"
version = "0.3.2"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand All @@ -10,7 +10,7 @@ OpenTelemetrySDK = "f5929ecf-be04-446c-b2f2-494e1fe70ee4"
URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"

[compat]
HTTP = "1"
HTTP = "1, 2"
OpenTelemetrySDK = "0.4"
URIs = "1"
julia = "1"
Expand Down
19 changes: 11 additions & 8 deletions src/exporter/prometheus/src/OpenTelemetryExporterPrometheus.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@ export PrometheusExporter
using OpenTelemetrySDK
using HTTP

# A request handler returning an `HTTP.Response`. This works identically across
# HTTP.jl 1.x and 2.x. (HTTP 2.0 dropped the `stream = true` server mode and the
# `setstatus`/`setheader`/`startwrite` streaming helpers in favor of returning a
# `Response`; buffering the body here keeps a single code path for both.)
function handler(
io,
provider::Ref{MeterProvider},
resource_to_telemetry_conversion,
with_timestamp,
)
for ins in provider[].async_instruments
ins()
end
HTTP.setstatus(io, 200)
HTTP.setheader(io, "Content-Type" => "text/plain")
HTTP.startwrite(io)
io = IOBuffer()
text_based_format(io, provider[], resource_to_telemetry_conversion; with_timestamp)
nothing
HTTP.Response(200, ["Content-Type" => "text/plain"]; body = take!(io))
end

"""
Expand All @@ -40,7 +41,9 @@ r = MetricReader(PrometheusExporter())
Note that `PrometheusExporter` is a pull based exporter. There's no need to execute `r()` to update the metrics.
"""
mutable struct PrometheusExporter <: OpenTelemetrySDK.AbstractExporter
server::HTTP.Servers.Server
# Untyped: the running-server handle type differs between HTTP.jl versions
# (`HTTP.Servers.Server` on 1.x, `HTTP.Server` on 2.x).
server::Any
provider::Ref{MeterProvider}
function PrometheusExporter(;
host = OTEL_EXPORTER_PROMETHEUS_HOST(),
Expand All @@ -57,9 +60,9 @@ mutable struct PrometheusExporter <: OpenTelemetrySDK.AbstractExporter
router,
"GET",
path,
io -> handler(io, provider, resource_to_telemetry_conversion, with_timestamp),
_ -> handler(provider, resource_to_telemetry_conversion, with_timestamp),
)
server = HTTP.serve!(router, host, port; stream = true, kw...)
server = HTTP.serve!(router, host, port; kw...)

new(server, provider)
end
Expand Down
Loading