diff --git a/Cargo.toml b/Cargo.toml index 2b1a59e1..181f5b52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,19 @@ description = "A reference implementation for provisioning Linux VMs on Azure." exitcode = "1.1.2" anyhow = "1.0.81" tokio = { version = "1", features = ["full"] } +opentelemetry_sdk = "0.21" +opentelemetry = "0.21" +tracing = "0.1" + [dependencies.libazureinit] path = "libazureinit" version = "0.1.0" +[dependencies.azurekvp] +path = "azurekvp" +version = "0.1.0" + [profile.dev] incremental = true @@ -31,4 +39,5 @@ path = "tests/functional_tests.rs" [workspace] members = [ "libazureinit", + "azurekvp", ] diff --git a/azurekvp/Cargo.toml b/azurekvp/Cargo.toml new file mode 100644 index 00000000..bc20013d --- /dev/null +++ b/azurekvp/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "azurekvp" +version = "0.1.1" +edition = "2021" +repository = "https://github.com/Azure/azure-init/" +homepage = "https://github.com/Azure/azure-init/" +license = "MIT" +description = "A binary library for implementing OpenTelemetry KVP for Linux VMs on Azure." + + +[dependencies] +once_cell = "1.12.0" +opentelemetry = "0.18.0" +opentelemetry_sdk = "0.22.0" +opentelemetry-stdout = "0.2.0" +tracing = "0.1" +tracing-opentelemetry = "0.18.0" +tracing-subscriber = "0.3.11" +serde = { version = "1.0" } +serde_json = "1.0.68" +tokio = { version = "1", features = ["full"] } +libc = "0.2" + +[lib] +name = "azurekvp" +path = "src/tracing.rs" \ No newline at end of file diff --git a/azurekvp/src/lib.rs b/azurekvp/src/lib.rs new file mode 100644 index 00000000..a6b6f9b8 --- /dev/null +++ b/azurekvp/src/lib.rs @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +pub mod main; diff --git a/azurekvp/src/tracing.rs b/azurekvp/src/tracing.rs new file mode 100644 index 00000000..8fa105f7 --- /dev/null +++ b/azurekvp/src/tracing.rs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +use opentelemetry::{ trace::{self, TracerProvider}, trace::Tracer as _}; +use opentelemetry::sdk::trace as sdktrace; +use opentelemetry::sdk::export::trace::stdout; +use opentelemetry::global; +use tracing_opentelemetry::OpenTelemetryLayer; +use once_cell::sync::Lazy; +use std::fs::File; +use std::os::unix::io::AsRawFd; +use libc::dup2; +use tracing_subscriber::{Registry, layer::SubscriberExt}; + + +pub static TRACER: Lazy<()> = Lazy::new(|| { + // Redirect stdout to a file + let log_file_path = "spans.log"; + let file = File::create(log_file_path).expect("Failed to create log file"); + let stdout_fd = file.as_raw_fd(); + unsafe { + dup2(stdout_fd, libc::STDOUT_FILENO); + } + + // Set up the stdout exporter correctly + let exporter = stdout::Exporter::new(std::io::stdout(), true); + + // Set up the TracerProvider with the stdout exporter + let provider = sdktrace::TracerProvider::builder() + .with_simple_exporter(exporter) + .build(); + + global::set_tracer_provider(provider.clone()); + + let tracer = provider.tracer("azure-kvp"); + // Create the OpenTelemetry layer using the SDK tracer + let otel_layer = OpenTelemetryLayer::new(tracer); + + // Create a `tracing` subscriber + let subscriber = Registry::default() + .with(otel_layer); + + // Set the subscriber as the global default + tracing::subscriber::set_global_default(subscriber) + .expect("Setting default subscriber failed"); +}); + +pub fn initialize_tracing() { + Lazy::force(&TRACER); +} \ No newline at end of file diff --git a/spans.log b/spans.log new file mode 100644 index 00000000..b4dc6e25 --- /dev/null +++ b/spans.log @@ -0,0 +1,376 @@ +SpanData { + span_context: SpanContext { + trace_id: ecea5cd2e78812b3e9bad50d3973bde3, + span_id: ef78e8890b27fedb, + trace_flags: TraceFlags( + 1, + ), + is_remote: false, + trace_state: TraceState( + None, + ), + }, + parent_span_id: 0000000000000000, + span_kind: Internal, + name: "test", + start_time: SystemTime { + tv_sec: 1714773090, + tv_nsec: 869927907, + }, + end_time: SystemTime { + tv_sec: 1714773090, + tv_nsec: 870027565, + }, + attributes: EvictedHashMap { + map: { + Static( + "idle_ns", + ): I64( + 106123, + ), + Static( + "code.lineno", + ): I64( + 53, + ), + Static( + "code.namespace", + ): String( + Static( + "azure_init", + ), + ), + Static( + "code.filepath", + ): String( + Static( + "src/main.rs", + ), + ), + Static( + "thread.name", + ): String( + Owned( + "main", + ), + ), + Static( + "busy_ns", + ): I64( + 5625, + ), + Static( + "thread.id", + ): I64( + 1, + ), + }, + evict_list: [ + Static( + "idle_ns", + ), + Static( + "busy_ns", + ), + Static( + "thread.name", + ), + Static( + "thread.id", + ), + Static( + "code.lineno", + ), + Static( + "code.namespace", + ), + Static( + "code.filepath", + ), + ], + max_len: 128, + dropped_count: 0, + }, + events: EvictedQueue { + queue: None, + max_len: 128, + dropped_count: 0, + }, + links: EvictedQueue { + queue: None, + max_len: 128, + dropped_count: 0, + }, + status: Unset, + resource: Resource { + attrs: { + Static( + "service.name", + ): String( + Owned( + "unknown_service", + ), + ), + }, + schema_url: None, + }, + instrumentation_lib: InstrumentationLibrary { + name: "azure-kvp", + version: None, + schema_url: None, + }, +} +SpanData { + span_context: SpanContext { + trace_id: 4fac9eb4d14424ba354d2bcc375dcc34, + span_id: 5a3fcbb7b214e95b, + trace_flags: TraceFlags( + 1, + ), + is_remote: false, + trace_state: TraceState( + None, + ), + }, + parent_span_id: 0000000000000000, + span_kind: Internal, + name: "get_username", + start_time: SystemTime { + tv_sec: 1714773090, + tv_nsec: 880088576, + }, + end_time: SystemTime { + tv_sec: 1714773090, + tv_nsec: 880662450, + }, + attributes: EvictedHashMap { + map: { + Static( + "thread.id", + ): I64( + 1, + ), + Static( + "busy_ns", + ): I64( + 329559, + ), + Static( + "idle_ns", + ): I64( + 234248, + ), + Static( + "thread.name", + ): String( + Owned( + "main", + ), + ), + Static( + "imds_body", + ): String( + Owned( + "\"{\\\"compute\\\":{\\\"azEnvironment\\\":\\\"AzurePublicCloud\\\",\\\"customData\\\":\\\"\\\",\\\"evictionPolicy\\\":\\\"\\\",\\\"isHostCompatibilityLayerVm\\\":\\\"false\\\",\\\"licenseType\\\":\\\"\\\",\\\"location\\\":\\\"westus2\\\",\\\"name\\\":\\\"93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe\\\",\\\"offer\\\":\\\"\\\",\\\"osProfile\\\":{\\\"adminUsername\\\":\\\"cloudenv\\\",\\\"computerName\\\":\\\"93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe\\\",\\\"disablePasswordAuthentication\\\":\\\"true\\\"},\\\"osType\\\":\\\"Linux\\\",\\\"placementGroupId\\\":\\\"\\\",\\\"plan\\\":{\\\"name\\\":\\\"\\\",\\\"product\\\":\\\"\\\",\\\"publisher\\\":\\\"\\\"},\\\"platformFaultDomain\\\":\\\"0\\\",\\\"platformUpdateDomain\\\":\\\"0\\\",\\\"priority\\\":\\\"\\\",\\\"provider\\\":\\\"Microsoft.Compute\\\",\\\"publicKeys\\\":[{\\\"keyData\\\":\\\"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPYyB2V9q43oWBJINIZMzJ4zrYoNptGCK9i28qxj9cS2Af/FkrVYTSSRMPJforJRVkyY/6M63TFzfIeMe6b93g9Q4nDoxyUDMJ5SEkLp3kw3caxrimLQF2yJz4QySoiqaFlhfot9bP3En9i8AQYjogQtxQqpw77RRzQOkinP5gyga5W2Ia/inNGBRwF2guqZccsOrTI2WF6dnHTB28LIxhHox/WH+0CmMKQrP8yX3bzoReXvsmm8RztC6PWb3G9FzEXK6fDdaLApSIvO/sc5MSEEdbwx7yo2phWsv96x7wY3QZtUGg+ZZnrtr/RE05xQPHm+ufh7qwbF87Ekt70h9R vsonline@machine\\\",\\\"path\\\":\\\"/home/cloudenv/.ssh/authorized_keys\\\"}],\\\"publisher\\\":\\\"\\\",\\\"resourceGroupName\\\":\\\"vsclk-online-prod-rel-usw2-040\\\",\\\"resourceId\\\":\\\"/subscriptions/75bc2f80-0696-46fc-9e0b-afcddbb5dc40/resourceGroups/vsclk-online-prod-rel-usw2-040/providers/Microsoft.Compute/virtualMachines/93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe\\\",\\\"securityProfile\\\":{\\\"secureBootEnabled\\\":\\\"false\\\",\\\"virtualTpmEnabled\\\":\\\"false\\\"},\\\"sku\\\":\\\"\\\",\\\"storageProfile\\\":{\\\"dataDisks\\\":[],\\\"imageReference\\\":{\\\"id\\\":\\\"/subscriptions/979523fb-a19c-4bb0-a8ee-cef29597b0a4/resourceGroups/vsclk-online-prod-images-usw2/providers/Microsoft.Compute/galleries/gallery_usw2/images/ubuntu/versions/2024.0419.001\\\",\\\"offer\\\":\\\"\\\",\\\"publisher\\\":\\\"\\\",\\\"sku\\\":\\\"\\\",\\\"version\\\":\\\"\\\"},\\\"osDisk\\\":{\\\"caching\\\":\\\"ReadOnly\\\",\\\"createOption\\\":\\\"FromImage\\\",\\\"diffDiskSettings\\\":{\\\"option\\\":\\\"Local\\\"},\\\"diskSizeGB\\\":\\\"30\\\",\\\"encryptionSettings\\\":{\\\"enabled\\\":\\\"false\\\"},\\\"image\\\":{\\\"uri\\\":\\\"\\\"},\\\"managedDisk\\\":{\\\"id\\\":\\\"/subscriptions/75bc2f80-0696-46fc-9e0b-afcddbb5dc40/resourceGroups/vsclk-online-prod-rel-usw2-040/providers/Microsoft.Compute/disks/93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe-disk\\\",\\\"storageAccountType\\\":\\\"Standard_LRS\\\"},\\\"name\\\":\\\"93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe-disk\\\",\\\"osType\\\":\\\"Linux\\\",\\\"vhd\\\":{\\\"uri\\\":\\\"\\\"},\\\"writeAcceleratorEnabled\\\":\\\"false\\\"},\\\"resourceDisk\\\":{\\\"size\\\":\\\"76800\\\"}},\\\"subscriptionId\\\":\\\"75bc2f80-0696-46fc-9e0b-afcddbb5dc40\\\",\\\"tags\\\":\\\"ComputeOS:Linux;OperationReason:WatchPoolSizeIncrease;PoolDefinition:c134d4e6c324e78e88996774746a60b93a0a9a43;PoolImageFamilyName:customUbuntuServer;PoolImageName:/subscriptions/979523fb-a19c-4bb0-a8ee-cef29597b0a4/resourceGroups/vsclk-online-prod-images-usw2/providers/Microsoft.Compute/galleries/gallery_usw2/images/ubuntu/versions/2024.0419.001;PoolLocation:westus2;PoolSkuName:Standard_D2ds_v5;PoolVersionDefinition:a88d797aeaefa8ecf4465d5e20cb0699330c60c4;ResourceComponentRecordIds:dc819a97-da14-4cb1-8ff6-51e82d20ec8f,7b8c6fa1-5b97-4f4b-bcbe-5438e48ee350,b449b564-5c26-4f1e-a872-77033e0a1370,b5c5abfa-d5a6-49cd-8fcf-9fcae36adc27,55cab94f-06b5-4b5b-bd53-c32770b2f75d;ResourceId:93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe;ResourceName:93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe;ResourceType:ComputeVM;platformsettings.host_environment.service.platform_optedin_for_rootcerts:true\\\",\\\"tagsList\\\":[{\\\"name\\\":\\\"ComputeOS\\\",\\\"value\\\":\\\"Linux\\\"},{\\\"name\\\":\\\"OperationReason\\\",\\\"value\\\":\\\"WatchPoolSizeIncrease\\\"},{\\\"name\\\":\\\"PoolDefinition\\\",\\\"value\\\":\\\"c134d4e6c324e78e88996774746a60b93a0a9a43\\\"},{\\\"name\\\":\\\"PoolImageFamilyName\\\",\\\"value\\\":\\\"customUbuntuServer\\\"},{\\\"name\\\":\\\"PoolImageName\\\",\\\"value\\\":\\\"/subscriptions/979523fb-a19c-4bb0-a8ee-cef29597b0a4/resourceGroups/vsclk-online-prod-images-usw2/providers/Microsoft.Compute/galleries/gallery_usw2/images/ubuntu/versions/2024.0419.001\\\"},{\\\"name\\\":\\\"PoolLocation\\\",\\\"value\\\":\\\"westus2\\\"},{\\\"name\\\":\\\"PoolSkuName\\\",\\\"value\\\":\\\"Standard_D2ds_v5\\\"},{\\\"name\\\":\\\"PoolVersionDefinition\\\",\\\"value\\\":\\\"a88d797aeaefa8ecf4465d5e20cb0699330c60c4\\\"},{\\\"name\\\":\\\"ResourceComponentRecordIds\\\",\\\"value\\\":\\\"dc819a97-da14-4cb1-8ff6-51e82d20ec8f,7b8c6fa1-5b97-4f4b-bcbe-5438e48ee350,b449b564-5c26-4f1e-a872-77033e0a1370,b5c5abfa-d5a6-49cd-8fcf-9fcae36adc27,55cab94f-06b5-4b5b-bd53-c32770b2f75d\\\"},{\\\"name\\\":\\\"ResourceId\\\",\\\"value\\\":\\\"93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe\\\"},{\\\"name\\\":\\\"ResourceName\\\",\\\"value\\\":\\\"93ebfb57-6bdd-4f3e-8ac0-d60156e71fbe\\\"},{\\\"name\\\":\\\"ResourceType\\\",\\\"value\\\":\\\"ComputeVM\\\"},{\\\"name\\\":\\\"platformsettings.host_environment.service.platform_optedin_for_rootcerts\\\",\\\"value\\\":\\\"true\\\"}],\\\"userData\\\":\\\"\\\",\\\"version\\\":\\\"2024.0419.001\\\",\\\"vmId\\\":\\\"ecfeff26-c7b4-4778-96d5-2acfd6b80c2a\\\",\\\"vmScaleSetName\\\":\\\"\\\",\\\"vmSize\\\":\\\"Standard_D2ds_v5\\\",\\\"zone\\\":\\\"\\\"},\\\"network\\\":{\\\"interface\\\":[{\\\"ipv4\\\":{\\\"ipAddress\\\":[{\\\"privateIpAddress\\\":\\\"172.16.5.4\\\",\\\"publicIpAddress\\\":\\\"\\\"}],\\\"subnet\\\":[{\\\"address\\\":\\\"172.16.5.0\\\",\\\"prefix\\\":\\\"24\\\"}]},\\\"ipv6\\\":{\\\"ipAddress\\\":[]},\\\"macAddress\\\":\\\"000D3A078740\\\"}]}}\"", + ), + ), + Static( + "code.filepath", + ): String( + Static( + "src/main.rs", + ), + ), + Static( + "code.lineno", + ): I64( + 20, + ), + Static( + "code.namespace", + ): String( + Static( + "azure_init", + ), + ), + }, + evict_list: [ + Static( + "idle_ns", + ), + Static( + "busy_ns", + ), + Static( + "imds_body", + ), + Static( + "thread.name", + ), + Static( + "thread.id", + ), + Static( + "code.lineno", + ), + Static( + "code.namespace", + ), + Static( + "code.filepath", + ), + ], + max_len: 128, + dropped_count: 0, + }, + events: EvictedQueue { + queue: None, + max_len: 128, + dropped_count: 0, + }, + links: EvictedQueue { + queue: None, + max_len: 128, + dropped_count: 0, + }, + status: Unset, + resource: Resource { + attrs: { + Static( + "service.name", + ): String( + Owned( + "unknown_service", + ), + ), + }, + schema_url: None, + }, + instrumentation_lib: InstrumentationLibrary { + name: "azure-kvp", + version: None, + schema_url: None, + }, +} +SpanData { + span_context: SpanContext { + trace_id: e5f08ba136344eb0c6e387a5a21ed849, + span_id: a22ea2674c9dd6dd, + trace_flags: TraceFlags( + 1, + ), + is_remote: false, + trace_state: TraceState( + None, + ), + }, + parent_span_id: 0000000000000000, + span_kind: Internal, + name: "query-imds", + start_time: SystemTime { + tv_sec: 1714773090, + tv_nsec: 880038063, + }, + end_time: SystemTime { + tv_sec: 1714773090, + tv_nsec: 977431564, + }, + attributes: EvictedHashMap { + map: { + Static( + "busy_ns", + ): I64( + 4152, + ), + Static( + "thread.id", + ): I64( + 1, + ), + Static( + "idle_ns", + ): I64( + 37600, + ), + Static( + "code.lineno", + ): I64( + 82, + ), + Static( + "code.filepath", + ): String( + Static( + "src/main.rs", + ), + ), + Static( + "code.namespace", + ): String( + Static( + "azure_init", + ), + ), + Static( + "thread.name", + ): String( + Owned( + "main", + ), + ), + }, + evict_list: [ + Static( + "idle_ns", + ), + Static( + "busy_ns", + ), + Static( + "thread.name", + ), + Static( + "thread.id", + ), + Static( + "code.lineno", + ), + Static( + "code.namespace", + ), + Static( + "code.filepath", + ), + ], + max_len: 128, + dropped_count: 0, + }, + events: EvictedQueue { + queue: None, + max_len: 128, + dropped_count: 0, + }, + links: EvictedQueue { + queue: None, + max_len: 128, + dropped_count: 0, + }, + status: Unset, + resource: Resource { + attrs: { + Static( + "service.name", + ): String( + Owned( + "unknown_service", + ), + ), + }, + schema_url: None, + }, + instrumentation_lib: InstrumentationLibrary { + name: "azure-kvp", + version: None, + schema_url: None, + }, +} diff --git a/src/main.rs b/src/main.rs index 86068f45..317d7374 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,10 +14,18 @@ use libazureinit::{ reqwest::{header, Client}, user, }; +use azurekvp::{initialize_tracing, TRACER}; +use opentelemetry::global; +use tracing::{info, instrument}; +use opentelemetry::trace::Tracer; +use opentelemetry::trace::Span; +use tracing::span; +use tracing::Level; const VERSION: &str = env!("CARGO_PKG_VERSION"); // Mount the given device, get OVF environment data, return it. +#[instrument] fn mount_parse_ovf_env(dev: String) -> Result { let mount_media = Media::new(PathBuf::from(dev), PathBuf::from(media::PATH_MOUNT_POINT)); @@ -64,6 +72,11 @@ fn get_username(imds_body: String) -> Result { } } +#[instrument] +fn test () { + print!("Hello, World!"); +} + #[tokio::main] async fn main() -> ExitCode { match provision().await { @@ -85,6 +98,9 @@ async fn main() -> ExitCode { } async fn provision() -> Result<(), anyhow::Error> { + // Initialize the tracing subscriber + initialize_tracing(); + let mut default_headers = header::HeaderMap::new(); let user_agent = header::HeaderValue::from_str( format!("azure-init v{VERSION}").as_str(),