Skip to content

Commit

Permalink
feat: add methodfrom_env to promethes exporter builder
Browse files Browse the repository at this point in the history
Fixes #293

Allows configuring the `PrometheusExporter` using environment variables defined in the semantic conventions of the Otel specification. Currently, supports setting the host and port for prometheus in the builder and will fall back to the defaults defined in the otel specification.
  • Loading branch information
LanceEa committed Jul 30, 2021
1 parent ae4aeb3 commit bf7106f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 0 deletions.
8 changes: 8 additions & 0 deletions opentelemetry-prometheus/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v0.9.0

### Added

- Add `from_env` method to prometheus exporter based on semantic environment vars

## v0.8.0

### Changed
Expand All @@ -15,9 +21,11 @@
## v0.6.0

### Added

- Add sanitization of prometheus label names #462

### Changed

- Update to opentelemetry v0.13.0
- Update prometheus dependency #485

Expand Down
71 changes: 71 additions & 0 deletions opentelemetry-prometheus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ use opentelemetry::{
metrics::{registry::RegistryMeterProvider, MetricsError, NumberKind},
Key, Value,
};
use std::env;
use std::sync::{Arc, Mutex};
use std::time::Duration;

Expand Down Expand Up @@ -122,9 +123,42 @@ pub struct ExporterBuilder {
///
/// If not set a new empty `Registry` is created.
registry: Option<prometheus::Registry>,

/// The host used by the prometheus exporter
///
/// If not set it will be defaulted to all addresses "0.0.0.0"
host: Option<String>,

/// The port used by the prometheus exporter
///
/// If not set it will be defaulted to port "9464"
port: Option<String>,
}

impl ExporterBuilder {
/// Set builder fields for host and port from the OS environment variables
///
/// Fields set by developer takes precedent and the OS environment variables will be ignored
pub fn from_env() -> Self {
let mut builder = ExporterBuilder::default();

if let Some(host) = env::var("OTEL_EXPORTER_PROMETHEUS_HOST")
.ok()
.filter(|s| !s.is_empty())
{
builder = builder.with_host(host)
}

if let Some(port) = env::var("OTEL_EXPORTER_PROMETHEUS_PORT")
.ok()
.filter(|s| !s.is_empty())
{
builder = builder.with_port(port);
}

builder
}

/// Set the resource to be associated with all `Meter`s for this exporter
pub fn with_resource(self, resource: Resource) -> Self {
ExporterBuilder {
Expand Down Expand Up @@ -160,6 +194,22 @@ impl ExporterBuilder {
}
}

/// Set the host for the prometheus exporter
pub fn with_host(self, host: String) -> Self {
ExporterBuilder {
host: Some(host),
..self
}
}

/// Set the port for the prometheus exporter
pub fn with_port(self, port: String) -> Self {
ExporterBuilder {
port: Some(port),
..self
}
}

/// Set the prometheus registry to be used by this exporter
pub fn with_registry(self, registry: prometheus::Registry) -> Self {
ExporterBuilder {
Expand Down Expand Up @@ -189,11 +239,16 @@ impl ExporterBuilder {

global::set_meter_provider(controller.provider());

let host = self.host.unwrap_or_else(|| "0.0.0.0".to_string());
let port = self.port.unwrap_or_else(|| "9464".to_string());

PrometheusExporter::new(
registry,
controller,
default_summary_quantiles,
default_histogram_boundaries,
host,
port,
)
}

Expand All @@ -218,6 +273,8 @@ pub struct PrometheusExporter {
controller: Arc<Mutex<PullController>>,
default_summary_quantiles: Vec<f64>,
default_histogram_boundaries: Vec<f64>,
host: String,
port: String,
}

impl PrometheusExporter {
Expand All @@ -227,6 +284,8 @@ impl PrometheusExporter {
controller: PullController,
default_summary_quantiles: Vec<f64>,
default_histogram_boundaries: Vec<f64>,
host: String,
port: String,
) -> Result<Self, MetricsError> {
let controller = Arc::new(Mutex::new(controller));
let collector = Collector::with_controller(controller.clone());
Expand All @@ -239,6 +298,8 @@ impl PrometheusExporter {
controller,
default_summary_quantiles,
default_histogram_boundaries,
host,
port,
})
}

Expand All @@ -254,6 +315,16 @@ impl PrometheusExporter {
.map_err(Into::into)
.map(|locked| locked.provider())
}

/// Get the exporters host for prometheus.
pub fn host(&self) -> &str {
self.host.as_str()
}

/// Get the exporters port for prometheus.
pub fn port(&self) -> &str {
self.port.as_str()
}
}

#[derive(Debug)]
Expand Down
30 changes: 30 additions & 0 deletions opentelemetry-prometheus/tests/integration_test.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::env;

use opentelemetry::sdk::Resource;
use opentelemetry::{
metrics::{BatchObserverResult, MeterProvider, ObserverResult},
Expand Down Expand Up @@ -159,3 +161,31 @@ fn compare_export(exporter: &PrometheusExporter, mut expected: Vec<&'static str>

assert_eq!(expected.join("\n"), metrics_only.join("\n"))
}

#[test]
fn test_from_env() {
let otel_exporter_prometheus_host = "OTEL_EXPORTER_PROMETHEUS_HOST";
let otel_exporter_prometheus_port = "OTEL_EXPORTER_PROMETHEUS_PORT";

// environment variables do not exist
env::remove_var(otel_exporter_prometheus_host);
env::remove_var(otel_exporter_prometheus_port);
let exporter = opentelemetry_prometheus::ExporterBuilder::from_env().init();
assert_eq!(exporter.host(), "0.0.0.0");
assert_eq!(exporter.port(), "9464");

// environment variables are available and non-empty strings
env::set_var(otel_exporter_prometheus_host, "prometheus-test");
env::set_var(otel_exporter_prometheus_port, "9000");

let exporter = opentelemetry_prometheus::ExporterBuilder::from_env().init();
assert_eq!(exporter.host(), "prometheus-test");
assert_eq!(exporter.port(), "9000");

// environment variables are available and empty
env::set_var(otel_exporter_prometheus_host, "");
env::set_var(otel_exporter_prometheus_port, "");
let exporter = opentelemetry_prometheus::ExporterBuilder::from_env().init();
assert_eq!(exporter.host(), "0.0.0.0");
assert_eq!(exporter.port(), "9464");
}

0 comments on commit bf7106f

Please sign in to comment.