aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.rs57
-rw-r--r--src/main.rs74
2 files changed, 129 insertions, 2 deletions
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..153c170
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,57 @@
+use std::sync::LazyLock;
+
+use anyhow::Result;
+use confique::Config;
+use opentelemetry_otlp::Protocol;
+
+#[derive(Config)]
+pub struct CspyConfig {
+ #[config(env = "CSPY_DOCKER_SOCKET")]
+ pub docker_socket: Option<String>,
+
+ #[config(env = "CSPY_OTLP_PROTO", default = "httpbinary", deserialize_with = crate::config::deser_protocol)]
+ pub otlp_protocol: Protocol,
+
+ #[config(env = "CSPY_OTLP_ENDPOINT")]
+ pub otlp_endpoint: Option<String>,
+}
+
+pub static CONFIG: LazyLock<CspyConfig> = LazyLock::new(|| {
+ let cfg_loc = std::env::var("CSPY_CONFIG");
+ let cfg_loc = cfg_loc.as_deref().ok().unwrap_or(&"/etc/containerspy/config.json");
+
+ CspyConfig::builder()
+ .env()
+ .file(cfg_loc)
+ .load()
+ .unwrap()
+});
+
+
+/// deserialization boilerplate
+struct ProtoDeserVisitor;
+
+/// deserialization boilerplate
+impl<'de> confique::serde::de::Visitor<'de> for ProtoDeserVisitor {
+ type Value = Protocol;
+
+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+ formatter.write_str(r#""httpbinary", "httpjson", or "grpc"."#)
+ }
+
+ fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
+ where
+ E: confique::serde::de::Error, {
+ Ok(match v {
+ "httpbinary" => Protocol::HttpBinary,
+ "httpjson" => Protocol::HttpJson,
+ "grpc" => Protocol::Grpc,
+ &_ => return Err(E::custom(format!("{v} is not a valid OTLP protocol, valid options are httpbinary, httpjson, or grpc.")))
+ })
+ }
+}
+
+/// deserialization boilerplate
+fn deser_protocol<'de, D: confique::serde::Deserializer<'de>>(d: D) -> Result<Protocol, D::Error> {
+ d.deserialize_str(ProtoDeserVisitor)
+}
diff --git a/src/main.rs b/src/main.rs
index e7a11a9..3e1b75c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,73 @@
-fn main() {
- println!("Hello, world!");
+use std::time::Duration;
+
+use anyhow::Result;
+use bollard::Docker;
+use config::CONFIG;
+use opentelemetry::{metrics::MeterProvider, KeyValue};
+use opentelemetry_otlp::{MetricExporter, Protocol, WithExportConfig};
+use opentelemetry_sdk::{metrics::SdkMeterProvider, Resource};
+
+mod config;
+
+#[tokio::main(flavor = "current_thread")]
+async fn main() -> Result<()> {
+ /* // open a docker connection
+ let docker =
+ if let Some(path) = &CONFIG.docker_socket {
+ Docker::connect_with_socket(path, 60, bollard::API_DEFAULT_VERSION)?
+ }
+ else {
+ Docker::connect_with_local_defaults()?
+ };
+
+ let info = docker.info().await?;
+
+ println!("Connected to Docker Daemon version {:?}", info.server_version); */
+
+ // connect the OTLP exporter
+ let metric_exporter =
+ match CONFIG.otlp_protocol {
+ Protocol::HttpBinary | Protocol::HttpJson => {
+ let builder = MetricExporter::builder().with_http().with_protocol(CONFIG.otlp_protocol);
+ let builder =
+ if let Some(e) = &CONFIG.otlp_endpoint {
+ println!("{e}");
+ builder.with_endpoint(e)
+ } else {
+ builder
+ };
+
+ builder.build()?
+ },
+ Protocol::Grpc => {
+ let builder = MetricExporter::builder().with_tonic().with_protocol(Protocol::Grpc);
+
+ let builder =
+ if let Some(e) = &CONFIG.otlp_endpoint {
+ builder.with_endpoint(e.as_str())
+ } else {
+ builder
+ };
+
+ builder.build()?
+ },
+ };
+
+ //let test_resource = Resource::builder().with_service_name("containerspy").build();
+
+ let meter_provider = SdkMeterProvider::builder()
+ //.with_resource(test_resource)
+ //.with_periodic_exporter(opentelemetry_stdout::MetricExporter::default())
+ .with_periodic_exporter(metric_exporter)
+ .build();
+
+ let m = meter_provider
+ .meter("test_meter")
+ .u64_gauge("testing_gauge")
+ .build();
+
+ m.record(10, &[KeyValue::new("label", 4)]);
+
+
+ Ok(())
}