You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: main.rs
    path of file: ./repos/rust-template/rust+wasm/{{project-name}}/src.axum
    
    the code of the file until where you have to start completion: //! {{project-name}}

use anyhow::Result;
use axum::{extract::Extension, headers::HeaderName, routing::get, Router};
use axum_tracing_opentelemetry::{opentelemetry_tracing_layer, response_with_trace_layer};
use http::header;
use std::{
    future::ready,
    io,
    net::{IpAddr, Ipv4Addr, SocketAddr},
    time::Duration,
};
use tokio::signal::{
    self,
    unix::{signal, SignalKind},
};
use tower::ServiceBuilder;
use tower_http::{
    catch_panic::CatchPanicLayer, sensitive_headers::SetSensitiveHeadersLayer,
    timeout::TimeoutLayer, ServiceBuilderExt,
};
use tracing::info;
use tracing_subscriber::{
    filter::{dynamic_filter_fn, filter_fn, LevelFilter},
    prelude::*,
    EnvFilter,
};
use utoipa::OpenApi;
use utoipa_swagger_ui::SwaggerUi;
use {{crate_name}}::{
    docs::ApiDoc,
    metrics::{process, prom::setup_metrics_recorder},
    middleware::{self, request_ulid::MakeRequestUlid, runtime},
    router,
    routes::fallback::notfound_404,
    settings::{Otel, Settings},
    tracer::init_tracer,
    tracing_layers::{
        format_layer::LogFmtLayer,
        metrics_layer::{MetricsLayer, METRIC_META_PREFIX},
        storage_layer::StorageLayer,
    },
};

/// Request identifier field.
const REQUEST_ID: &str = "request_id";

#[tokio::main]
async fn main() -> Result<()> {
    let (stdout_writer, _stdout_guard) = tracing_appender::non_blocking(io::stdout());

    let settings = Settings::load()?;
    setup_tracing(stdout_writer, settings.otel())?;

    info!(
        subject = "app_settings",
        category = "init",
        "starting with settings: {:?}",
        settings,
    );

    let env = settings.environment();
    let recorder_handle = setup_metrics_recorder()?;

    let app_metrics = async {
        let metrics_router = Router::new()
            .route("/metric
    
async fn main() -> Result<()> {
    let (stdout_writer, _stdout_guard) = tracing_appender::non_blocking(io::stdout());

    let settings = Settings::load()?;
    setup_tracing(stdout_writer, settings.otel())?;

    info!(
        subject = "app_settings",
        category = "init",
        "starting with settings: {:?}",
        settings,
    );

    let env = settings.environment();
    let recorder_handle = setup_metrics_recorder()?;

    let app_metrics = async {
        let metrics_router = Router::new()
            .route("/metrics", get(move || ready(recorder_handle.render())))
            .fallback(notfound_404);

        let router = metrics_router.layer(CatchPanicLayer::custom(runtime::catch_panic));

        // Spawn tick-driven process collection task
        tokio::task::spawn(process::collect_metrics(
            settings.monitoring().process_collector_interval,
        ));

        serve("Metrics", router, settings.server().metrics_port).await
    };

    let app = async {
        let req_id = HeaderName::from_static(REQUEST_ID);
        let router = router::setup_app_router()
            .route_layer(axum::middleware::from_fn(middleware::metrics::track))
            .layer(Extension(env))
            // Include trace context as header into the response.
            .layer(response_with_trace_layer())
            // Opentelemetry tracing middleware.
            // This returns a `TraceLayer` configured to use
            // OpenTelemetryâ€™s conventional span field names.
            .layer(opentelemetry_tracing_layer())
            // Set and propagate "request_id" (as a ulid) per request.
            .layer(
                ServiceBuilder::new()
                    .set_request_id(req_id.clone(), MakeRequestUlid)
                    .propagate_request_id(req_id),
            )
            // Applies the `tower_http::timeout::Timeout` middleware which
            // applies a timeout to requests.
            .layer(TimeoutLayer::new(Duration::from_millis(
                settings.server().timeout_ms,
            )))
            // Catches runtime panics and converts them into
            // `500 Internal Server` responses.
            .layer(CatchPanicLayer::custom(runtime::catch_panic))
            // Mark headers as sensitive on both requests and responses.
            .layer(SetSensitiveHeadersLayer::new([header::AUTHORIZATION]))
            .merge(SwaggerUi::new("/swagger-ui").url("/api-doc/openapi.json", ApiDoc::openapi()));

        serve("Application", router, settings.server().port).await
    };

    tokio::try_join!(app, app_metrics)?;
    Ok(())
}