Skip to content

Commit b5bcf8f

Browse files
committed
feat: add structured logging instrumentation for step-level operations
- Add #[instrument] to infrastructure steps: * InitializeInfrastructureStep with initialize_infrastructure span * PlanInfrastructureStep with plan_infrastructure span * ApplyInfrastructureStep with apply_infrastructure span (includes auto_approve field) * GetInstanceInfoStep with get_instance_info span - Add #[instrument] to rendering steps: * RenderOpenTofuTemplatesStep with render_opentofu_templates span * RenderAnsibleTemplatesStep with render_ansible_templates span - Add #[instrument] to system, connectivity, software, and validation steps: * WaitForCloudInitStep with wait_cloud_init span * WaitForSSHConnectivityStep with wait_ssh_connectivity span * InstallDockerStep with install_docker span * InstallDockerComposeStep with install_docker_compose span * ValidateCloudInitCompletionStep with validate_cloud_init span * ValidateDockerInstallationStep with validate_docker span * ValidateDockerComposeInstallationStep with validate_docker_compose span This implements Phase 2 of the structured logging plan, creating complete two-level hierarchical spans (Commands → Steps) with consistent naming conventions and contextual fields following the plan specifications.
1 parent 8dcacd7 commit b5bcf8f

File tree

13 files changed

+86
-13
lines changed

13 files changed

+86
-13
lines changed

src/steps/connectivity/wait_ssh_connectivity.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use tracing::info;
1+
use tracing::{info, instrument};
22

33
use crate::command_wrappers::ssh::{SshClient, SshConnection, SshError};
44

@@ -24,6 +24,11 @@ impl WaitForSSHConnectivityStep {
2424
/// * SSH connectivity cannot be established within the timeout period
2525
/// * The SSH client fails to initialize
2626
/// * The SSH command execution fails
27+
#[instrument(
28+
name = "wait_ssh_connectivity",
29+
skip_all,
30+
fields(step_type = "connectivity", protocol = "ssh")
31+
)]
2732
pub async fn execute(&self) -> Result<(), SshError> {
2833
info!(
2934
step = "wait_ssh_connectivity",

src/steps/infrastructure/apply.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use tracing::info;
3+
use tracing::{info, instrument};
44

55
use crate::command::CommandError;
66
use crate::command_wrappers::opentofu::client::OpenTofuClient;
@@ -34,6 +34,15 @@ impl ApplyInfrastructureStep {
3434
/// * The `OpenTofu` apply fails
3535
/// * The working directory does not exist or is not accessible
3636
/// * The `OpenTofu` command execution fails
37+
#[instrument(
38+
name = "apply_infrastructure",
39+
skip_all,
40+
fields(
41+
step_type = "infrastructure",
42+
operation = "apply",
43+
auto_approve = %self.auto_approve
44+
)
45+
)]
3746
pub fn execute(&self) -> Result<(), CommandError> {
3847
info!(
3948
step = "apply_infrastructure",

src/steps/infrastructure/get_instance_info.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use tracing::info;
3+
use tracing::{info, instrument};
44

55
use crate::command_wrappers::opentofu::client::{InstanceInfo, OpenTofuClient, OpenTofuError};
66

@@ -28,6 +28,11 @@ impl GetInstanceInfoStep {
2828
/// * The output cannot be parsed as JSON
2929
/// * The `instance_info` section is missing or malformed
3030
/// * The working directory does not exist or is not accessible
31+
#[instrument(
32+
name = "get_instance_info",
33+
skip_all,
34+
fields(step_type = "infrastructure", operation = "info")
35+
)]
3136
pub fn execute(&self) -> Result<InstanceInfo, OpenTofuError> {
3237
info!(
3338
step = "get_instance_info",

src/steps/infrastructure/initialize.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use tracing::info;
3+
use tracing::{info, instrument};
44

55
use crate::command::CommandError;
66
use crate::command_wrappers::opentofu::client::OpenTofuClient;
@@ -24,6 +24,11 @@ impl InitializeInfrastructureStep {
2424
/// * The `OpenTofu` initialization fails
2525
/// * The working directory does not exist or is not accessible
2626
/// * The `OpenTofu` command execution fails
27+
#[instrument(
28+
name = "initialize_infrastructure",
29+
skip_all,
30+
fields(step_type = "infrastructure", operation = "init")
31+
)]
2732
pub fn execute(&self) -> Result<(), CommandError> {
2833
info!(
2934
step = "initialize_infrastructure",

src/steps/infrastructure/plan.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use tracing::info;
3+
use tracing::{info, instrument};
44

55
use crate::command::CommandError;
66
use crate::command_wrappers::opentofu::client::OpenTofuClient;
@@ -24,6 +24,11 @@ impl PlanInfrastructureStep {
2424
/// * The `OpenTofu` plan fails
2525
/// * The working directory does not exist or is not accessible
2626
/// * The `OpenTofu` command execution fails
27+
#[instrument(
28+
name = "plan_infrastructure",
29+
skip_all,
30+
fields(step_type = "infrastructure", operation = "plan")
31+
)]
2732
pub fn execute(&self) -> Result<(), CommandError> {
2833
info!(
2934
step = "plan_infrastructure",

src/steps/rendering/ansible_templates.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::PathBuf;
33
use std::sync::Arc;
44

55
use thiserror::Error;
6-
use tracing::info;
6+
use tracing::{info, instrument};
77

88
use crate::ansible::template_renderer::ConfigurationTemplateError;
99
use crate::ansible::AnsibleTemplateRenderer;
@@ -54,6 +54,11 @@ impl RenderAnsibleTemplatesStep {
5454
///
5555
/// Returns an error if the template rendering fails or if there are issues
5656
/// with the template manager or renderer.
57+
#[instrument(
58+
name = "render_ansible_templates",
59+
skip_all,
60+
fields(step_type = "rendering", template_type = "ansible")
61+
)]
5762
pub async fn execute(&self) -> Result<(), RenderAnsibleTemplatesError> {
5863
info!(
5964
step = "render_ansible_templates",

src/steps/rendering/opentofu_templates.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use tracing::info;
3+
use tracing::{info, instrument};
44

55
use crate::tofu::template_renderer::{ProvisionTemplateError, TofuTemplateRenderer};
66

@@ -23,6 +23,11 @@ impl RenderOpenTofuTemplatesStep {
2323
///
2424
/// Returns an error if the template rendering fails or if there are issues
2525
/// with the template manager or renderer.
26+
#[instrument(
27+
name = "render_opentofu_templates",
28+
skip_all,
29+
fields(step_type = "rendering", template_type = "opentofu")
30+
)]
2631
pub async fn execute(&self) -> Result<(), ProvisionTemplateError> {
2732
info!(
2833
step = "render_opentofu_templates",

src/steps/software/docker.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::sync::Arc;
2-
use tracing::info;
2+
use tracing::{info, instrument};
33

44
use crate::command::CommandError;
55
use crate::command_wrappers::ansible::AnsibleClient;
@@ -32,6 +32,11 @@ impl InstallDockerStep {
3232
/// - The install-docker playbook assumes the apt cache is already updated
3333
/// or will handle stale cache gracefully
3434
/// - We skip the update-apt-cache playbook in E2E tests to avoid CI network issues
35+
#[instrument(
36+
name = "install_docker",
37+
skip_all,
38+
fields(step_type = "software", component = "docker", method = "ansible")
39+
)]
3540
pub fn execute(&self) -> Result<(), CommandError> {
3641
info!(
3742
step = "install_docker",

src/steps/software/docker_compose.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::sync::Arc;
2-
use tracing::info;
2+
use tracing::{info, instrument};
33

44
use crate::command::CommandError;
55
use crate::command_wrappers::ansible::AnsibleClient;
@@ -26,6 +26,15 @@ impl InstallDockerComposeStep {
2626
/// * The Ansible client fails to execute the playbook
2727
/// * Docker Compose installation fails
2828
/// * The playbook execution fails for any other reason
29+
#[instrument(
30+
name = "install_docker_compose",
31+
skip_all,
32+
fields(
33+
step_type = "software",
34+
component = "docker_compose",
35+
method = "ansible"
36+
)
37+
)]
2938
pub fn execute(&self) -> Result<(), CommandError> {
3039
info!(
3140
step = "install_docker_compose",

src/steps/system/wait_cloud_init.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::sync::Arc;
2-
use tracing::info;
2+
use tracing::{info, instrument};
33

44
use crate::command::CommandError;
55
use crate::command_wrappers::ansible::AnsibleClient;
@@ -26,6 +26,11 @@ impl WaitForCloudInitStep {
2626
/// * The Ansible client fails to execute the playbook
2727
/// * Cloud-init has not completed within the timeout period
2828
/// * The playbook execution fails for any other reason
29+
#[instrument(
30+
name = "wait_cloud_init",
31+
skip_all,
32+
fields(step_type = "system", component = "cloud_init")
33+
)]
2934
pub fn execute(&self) -> Result<(), CommandError> {
3035
info!(
3136
step = "wait_cloud_init",

0 commit comments

Comments
 (0)