Getting started with Monium Traces
Monium Traces is a tool for tracing and analysis of distributed requests. You can use traces to search for causes of low performance and failures, and monitor the execution of specific requests. The system forms a part of Monium and makes use of its shared components, i.e., access management, data model, and unified interface.
Monium Traces parameters
-
Monium currently only accepts OpenTelemetry (OTLP)
data. -
Address for traces:
ingest.monium.yandex.cloud:443. -
To write logs, you will need a service account with the
monium.traces.writerrole and an API key. -
Trace viewing interface: Monium home page
> Traces.
Steps to set up tracing for an application
In this guide, you will set up the transfer of test traces using the gRPCurl utility. The test_trace_data.json file contains the pre-prepared test trace data; and the send_trace.sh script substitutes the dynamic data (trace.id, span date and time) in the test trace and sends it to Monium.
If you are not signed up to Yandex Cloud
-
Log in to the management console
or sign up. If not signed up yet, navigate to the management console and follow the instructions. -
On the Yandex Cloud Billing page
, make sure you have a linked billing account with theACTIVEorTRIAL_ACTIVEstatus. If you do not have a billing account yet, create one.If you have an active billing account, you can navigate to the cloud page
to create or select a folder for your infrastructure.
In the Yandex Cloud console
- Create a service account with the
monium.traces.writerrole. - Create an API key for the service account with
yc.monium.traces.writefor scope and save it. The API key will be used in the next step.
In your infrastructure or VM
-
Install gRPCurl
. -
Clone the OpenTelemetry repository containing the proto files for GRPC endpoints:
git clone https://github.com/open-telemetry/opentelemetry-proto.git -
Create a file named test_trace_data.json and paste the contents with test trace data into it:
test_trace_data.json
{ "resourceSpans": [ { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "frontend" } }, { "key": "service.version", "value": { "stringValue": "1.0.0" } }, { "key": "telemetry.sdk.name", "value": { "stringValue": "opentelemetry" } }, { "key": "telemetry.sdk.language", "value": { "stringValue": "nodejs" } }, { "key": "telemetry.sdk.version", "value": { "stringValue": "1.17.0" } } ] }, "scopeSpans": [ { "scope": { "name": "frontend-tracer", "version": "1.0.0" }, "spans": [ { "traceId": "{{TRACE_ID}}", "spanId": "M8kLx3vN9Qw=", "name": "HTTP GET /api/checkout", "kind": 2, "startTimeUnixNano": "{{START_TIME_1}}", "endTimeUnixNano": "{{END_TIME_1}}", "attributes": [ { "key": "http.method", "value": { "stringValue": "GET" } }, { "key": "http.url", "value": { "stringValue": "/api/checkout" } }, { "key": "http.status_code", "value": { "intValue": "200" } }, { "key": "http.user_agent", "value": { "stringValue": "Mozilla/5.0" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "P2nRg8kLmHs=", "parentSpanId": "M8kLx3vN9Qw=", "name": "getCart", "kind": 3, "startTimeUnixNano": "{{START_TIME_2}}", "endTimeUnixNano": "{{END_TIME_2}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.CartService" } }, { "key": "rpc.method", "value": { "stringValue": "GetCart" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "T9wVh2mKpLx=", "parentSpanId": "M8kLx3vN9Qw=", "name": "placeOrder", "kind": 3, "startTimeUnixNano": "{{START_TIME_3}}", "endTimeUnixNano": "{{END_TIME_3}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.CheckoutService" } }, { "key": "rpc.method", "value": { "stringValue": "PlaceOrder" } } ], "status": { "code": 1 } } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "cartservice" } }, { "key": "service.version", "value": { "stringValue": "1.0.0" } }, { "key": "telemetry.sdk.name", "value": { "stringValue": "opentelemetry" } }, { "key": "telemetry.sdk.language", "value": { "stringValue": "dotnet" } } ] }, "scopeSpans": [ { "scope": { "name": "cartservice-tracer", "version": "1.0.0" }, "spans": [ { "traceId": "{{TRACE_ID}}", "spanId": "R5bNj7xMqWt=", "parentSpanId": "P2nRg8kLmHs=", "name": "oteldemo.CartService/GetCart", "kind": 2, "startTimeUnixNano": "{{START_TIME_4}}", "endTimeUnixNano": "{{END_TIME_4}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.CartService" } }, { "key": "rpc.method", "value": { "stringValue": "GetCart" } }, { "key": "rpc.grpc.status_code", "value": { "intValue": "0" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "V8dKm4pLzNr=", "parentSpanId": "R5bNj7xMqWt=", "name": "redis.get", "kind": 3, "startTimeUnixNano": "{{START_TIME_5}}", "endTimeUnixNano": "{{END_TIME_5}}", "attributes": [ { "key": "db.system", "value": { "stringValue": "redis" } }, { "key": "db.operation", "value": { "stringValue": "GET" } }, { "key": "db.redis.database_index", "value": { "intValue": "0" } } ], "status": { "code": 1 } } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "checkoutservice" } }, { "key": "service.version", "value": { "stringValue": "1.0.0" } }, { "key": "telemetry.sdk.name", "value": { "stringValue": "opentelemetry" } }, { "key": "telemetry.sdk.language", "value": { "stringValue": "go" } } ] }, "scopeSpans": [ { "scope": { "name": "checkoutservice-tracer", "version": "1.0.0" }, "spans": [ { "traceId": "{{TRACE_ID}}", "spanId": "Q3mTk9wPvBz=", "parentSpanId": "T9wVh2mKpLx=", "name": "oteldemo.CheckoutService/PlaceOrder", "kind": 2, "startTimeUnixNano": "{{START_TIME_6}}", "endTimeUnixNano": "{{END_TIME_6}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.CheckoutService" } }, { "key": "rpc.method", "value": { "stringValue": "PlaceOrder" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "L6hFr2sKxMv=", "parentSpanId": "Q3mTk9wPvBz=", "name": "getProduct", "kind": 3, "startTimeUnixNano": "{{START_TIME_7}}", "endTimeUnixNano": "{{END_TIME_7}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.ProductCatalogService" } }, { "key": "rpc.method", "value": { "stringValue": "GetProduct" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "N4tYw8jRpKd=", "parentSpanId": "Q3mTk9wPvBz=", "name": "convertCurrency", "kind": 3, "startTimeUnixNano": "{{START_TIME_8}}", "endTimeUnixNano": "{{END_TIME_8}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.CurrencyService" } }, { "key": "rpc.method", "value": { "stringValue": "Convert" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "Z7kPm5vQxLw=", "parentSpanId": "Q3mTk9wPvBz=", "name": "chargeCard", "kind": 3, "startTimeUnixNano": "{{START_TIME_9}}", "endTimeUnixNano": "{{END_TIME_9}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.PaymentService" } }, { "key": "rpc.method", "value": { "stringValue": "Charge" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "H8rBn3kMtQs=", "parentSpanId": "Q3mTk9wPvBz=", "name": "shipOrder", "kind": 3, "startTimeUnixNano": "{{START_TIME_10}}", "endTimeUnixNano": "{{END_TIME_10}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.ShippingService" } }, { "key": "rpc.method", "value": { "stringValue": "ShipOrder" } } ], "status": { "code": 1 } }, { "traceId": "{{TRACE_ID}}", "spanId": "K2wCp6nLvRx=", "parentSpanId": "Q3mTk9wPvBz=", "name": "sendOrderConfirmation", "kind": 3, "startTimeUnixNano": "{{START_TIME_11}}", "endTimeUnixNano": "{{END_TIME_11}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.EmailService" } }, { "key": "rpc.method", "value": { "stringValue": "SendOrderConfirmation" } } ], "status": { "code": 1 } } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "productcatalogservice" } }, { "key": "service.version", "value": { "stringValue": "1.0.0" } }, { "key": "telemetry.sdk.name", "value": { "stringValue": "opentelemetry" } }, { "key": "telemetry.sdk.language", "value": { "stringValue": "go" } } ] }, "scopeSpans": [ { "scope": { "name": "productcatalog-tracer", "version": "1.0.0" }, "spans": [ { "traceId": "{{TRACE_ID}}", "spanId": "F9vTj4mNqBk=", "parentSpanId": "L6hFr2sKxMv=", "name": "oteldemo.ProductCatalogService/GetProduct", "kind": 2, "startTimeUnixNano": "{{START_TIME_12}}", "endTimeUnixNano": "{{END_TIME_12}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.ProductCatalogService" } }, { "key": "rpc.method", "value": { "stringValue": "GetProduct" } }, { "key": "app.product.id", "value": { "stringValue": "OLJCESPC7Z" } } ], "status": { "code": 1 } } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "currencyservice" } }, { "key": "service.version", "value": { "stringValue": "1.0.0" } }, { "key": "telemetry.sdk.name", "value": { "stringValue": "opentelemetry" } }, { "key": "telemetry.sdk.language", "value": { "stringValue": "cpp" } } ] }, "scopeSpans": [ { "scope": { "name": "currency-tracer", "version": "1.0.0" }, "spans": [ { "traceId": "{{TRACE_ID}}", "spanId": "D1sGk7xPwMn=", "parentSpanId": "N4tYw8jRpKd=", "name": "oteldemo.CurrencyService/Convert", "kind": 2, "startTimeUnixNano": "{{START_TIME_13}}", "endTimeUnixNano": "{{END_TIME_13}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.CurrencyService" } }, { "key": "rpc.method", "value": { "stringValue": "Convert" } }, { "key": "app.currency.conversion.from", "value": { "stringValue": "USD" } }, { "key": "app.currency.conversion.to", "value": { "stringValue": "EUR" } } ], "status": { "code": 1 } } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "paymentservice" } }, { "key": "service.version", "value": { "stringValue": "1.0.0" } }, { "key": "telemetry.sdk.name", "value": { "stringValue": "opentelemetry" } }, { "key": "telemetry.sdk.language", "value": { "stringValue": "nodejs" } } ] }, "scopeSpans": [ { "scope": { "name": "payment-tracer", "version": "1.0.0" }, "spans": [ { "traceId": "{{TRACE_ID}}", "spanId": "B5qHm2tKzPr=", "parentSpanId": "Z7kPm5vQxLw=", "name": "oteldemo.PaymentService/Charge", "kind": 2, "startTimeUnixNano": "{{START_TIME_14}}", "endTimeUnixNano": "{{END_TIME_14}}", "attributes": [ { "key": "rpc.system", "value": { "stringValue": "grpc" } }, { "key": "rpc.service", "value": { "stringValue": "oteldemo.PaymentService" } }, { "key": "rpc.method", "value": { "stringValue": "Charge" } }, { "key": "app.payment.amount", "value": { "stringValue": "99.99" } }, { "key": "app.payment.card_type", "value": { "stringValue": "visa" } } ], "status": { "code": 1 } } ] } ] } ] } -
Create a file named send_trace.sh and paste the contents of the trace sending script into it:
send_trace.sh
#!/bin/bash # OpenTelemetry Trace Sender Script # Sends trace data to Monium with realistic timestamps and unique trace IDs set -euo pipefail # ============================================================================= # CONFIGURATION VARIABLES # ============================================================================= # Monium configuration - loaded from environment variables # MONIUM_PROJECT and MONIUM_API_KEY must be set in the environment MONIUM_ENDPOINT="ingest.monium.yandex.cloud:443" # File paths PROTO_PATH="opentelemetry-proto" PROTO_FILE="opentelemetry/proto/collector/trace/v1/trace_service.proto" TRACE_FILE="test_trace_data.json" # gRPC service SERVICE_NAME="opentelemetry.proto.collector.trace.v1.TraceService/Export" # ============================================================================= # COLOR CODES FOR OUTPUT # ============================================================================= RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # ============================================================================= # UTILITY FUNCTIONS # ============================================================================= # Print colored output print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" >&2 } # Get current time in nanoseconds (cross-platform) get_current_nanos() { if [[ "$OSTYPE" == "darwin"* ]]; then # macOS - use Python for accurate nanosecond timestamps python3 -c "import time; print(int(time.time() * 1000000000))" else # Linux date +%s%N fi } # Generate a new trace ID (16 bytes, base64 encoded) generate_trace_id() { if command -v openssl &> /dev/null; then openssl rand -base64 16 | tr -d '\n' else # Fallback to /dev/urandom head -c 16 /dev/urandom | base64 | tr -d '\n' fi } # Generate random duration variation (±20% of base duration) generate_random_duration() { local base_duration=$1 local variation=$((base_duration / 5)) # 20% variation local min_duration=$((base_duration - variation)) local max_duration=$((base_duration + variation)) # Generate random number between min and max local random_duration=$((min_duration + RANDOM % (max_duration - min_duration + 1))) echo $random_duration } # Calculate timestamp with offset in milliseconds and random duration calculate_timestamp() { local base_time=$1 local offset_ms=$2 local base_duration_ms=$3 local random_duration_ms=$(generate_random_duration $base_duration_ms) local start_time=$((base_time + (offset_ms * 1000000))) local end_time=$((start_time + (random_duration_ms * 1000000))) echo "$start_time $end_time" } # ============================================================================= # VALIDATION FUNCTIONS # ============================================================================= check_dependencies() { print_info "Checking dependencies..." local missing_deps=() if ! command -v grpcurl &> /dev/null; then missing_deps+=("grpcurl") fi if [ ${#missing_deps[@]} -ne 0 ]; then print_error "Missing required dependencies: ${missing_deps[*]}" exit 1 fi print_success "All dependencies are available" } validate_configuration() { print_info "Validating configuration..." # Check if MONIUM_PROJECT is set if [[ -z "${MONIUM_PROJECT:-}" ]]; then print_error "MONIUM_PROJECT environment variable is not set" echo "Please set MONIUM_PROJECT environment variable:" echo " export MONIUM_PROJECT=your-project-name" exit 1 fi # Check if MONIUM_PROJECT is not empty if [[ -z "$MONIUM_PROJECT" ]]; then print_error "MONIUM_PROJECT environment variable is empty" echo "Please set MONIUM_PROJECT to a valid project name." exit 1 fi # Check if MONIUM_API_KEY is set if [[ -z "${MONIUM_API_KEY:-}" ]]; then print_error "MONIUM_API_KEY environment variable is not set" echo "Please set MONIUM_API_KEY environment variable:" echo " export MONIUM_API_KEY=your-api-key" exit 1 fi # Check if MONIUM_API_KEY is not empty if [[ -z "$MONIUM_API_KEY" ]]; then print_error "MONIUM_API_KEY environment variable is empty" echo "Please set MONIUM_API_KEY to a valid API key." exit 1 fi print_success "Configuration is valid" } validate_files() { print_info "Validating required files..." if [[ ! -f "$TRACE_FILE" ]]; then print_error "Trace file not found: $TRACE_FILE" exit 1 fi if [[ ! -d "$PROTO_PATH" ]]; then print_error "Proto path not found: $PROTO_PATH" exit 1 fi local full_proto_path="$PROTO_PATH/$PROTO_FILE" if [[ ! -f "$full_proto_path" ]]; then print_error "Proto file not found: $full_proto_path" exit 1 fi print_success "All required files are valid" } # ============================================================================= # JSON PROCESSING FUNCTIONS # ============================================================================= update_trace_json() { local input_file="$1" local output_file="$2" local new_trace_id="$3" local base_time="$4" print_info "Updating trace data with new timestamps and trace ID..." # Copy input to output first cp "$input_file" "$output_file" # Replace trace ID - escape special characters for sed local escaped_trace_id=$(echo "$new_trace_id" | sed 's/[\/&]/\\&/g') sed -i.bak "s/{{TRACE_ID}}/$escaped_trace_id/g" "$output_file" # Define span timings (offset_ms duration_ms) local span_timings=( "0 500" "10 50" "70 420" "15 40" "20 30" "75 410" "80 60" "150 40" "200 80" "290 100" "400 80" "85 50" "155 30" "205 70" ) # Build sed script for all replacements local sed_script="" for i in "${!span_timings[@]}"; do local timing=(${span_timings[$i]}) local offset_ms=${timing[0]} local duration_ms=${timing[1]} local timestamps=$(calculate_timestamp "$base_time" "$offset_ms" "$duration_ms") local start_time=$(echo $timestamps | cut -d' ' -f1) local end_time=$(echo $timestamps | cut -d' ' -f2) local index=$((i + 1)) sed_script="${sed_script} -e s/not_var{{START_TIME_$index}}/$start_time/g" sed_script="${sed_script} -e s/not_var{{END_TIME_$index}}/$end_time/g" done # Apply all replacements in one sed call eval sed -i.bak $sed_script "$output_file" rm -f "$output_file.bak" print_success "Trace data updated successfully" } # ============================================================================= # TRACE SENDING FUNCTION # ============================================================================= send_trace() { local trace_file=$1 print_info "Sending trace to Monium endpoint: $MONIUM_ENDPOINT" print_info "Project: $MONIUM_PROJECT" # Execute the grpcurl command if grpcurl \ -proto "$PROTO_PATH/$PROTO_FILE" \ -import-path "$PROTO_PATH" \ -d @ < "$trace_file" \ -H "Authorization: Api-Key $MONIUM_API_KEY" \ -H "x-monium-project: $MONIUM_PROJECT" \ "$MONIUM_ENDPOINT" \ "$SERVICE_NAME"; then print_success "Trace sent successfully!" else local exit_code=$? print_error "Failed to send trace (exit code: $exit_code)" echo echo "Common issues:" echo " - Check your API key and project name" echo " - Verify network connectivity to $MONIUM_ENDPOINT" echo " - Ensure the proto files are correct" exit $exit_code fi } # ============================================================================= # CLEANUP FUNCTION # ============================================================================= cleanup() { if [[ -n "${TEMP_FILE:-}" && -f "$TEMP_FILE" ]]; then rm -f "$TEMP_FILE" fi } # ============================================================================= # MAIN FUNCTION # ============================================================================= main() { echo "OpenTelemetry Trace Sender for Monium" echo # Set up cleanup trap trap cleanup EXIT # Run all validations check_dependencies validate_configuration validate_files echo print_info "Starting trace processing..." # Generate new trace ID local new_trace_id new_trace_id=$(generate_trace_id) # Calculate base time (current time - 500ms to account for total span duration) local current_nanos base_time current_nanos=$(get_current_nanos) base_time=$((current_nanos - 500000000)) # Create temporary file for updated JSON TEMP_FILE=$(mktemp) # Update the trace JSON with new timestamps and trace ID update_trace_json "$TRACE_FILE" "$TEMP_FILE" "$new_trace_id" "$base_time" echo print_info "Trace data prepared, sending to Monium..." echo # Send the trace send_trace "$TEMP_FILE" echo print_success "Trace processing completed successfully!" } # ============================================================================= # SCRIPT ENTRY POINT # ============================================================================= # Check if script is being sourced or executed if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi -
Create the
MONIUM_PROJECTandMONIUM_API_KEYenvironment variables and write your parameters into them:export MONIUM_PROJECT=<project_name> export MONIUM_API_KEY=<API_key>Where:
project_name:folder__<folder_ID_in_Yandex Cloud>, e.g.,folder__b1gv2q1ktr03hylke78j.API_key: API key you created earlier.
-
Add a permission to run the script:
chmod +x send_trace.sh -
Run the
./send_trace.shscript. -
View the traces in Monium.
Viewing traces
-
On the Monium home page
, select Traces on the left. -
At the top, set the search interval using the timeline, a preset interval, or by entering the time value directly.
-
Select Search by traces or Search by spans.
-
Enter a date search query.
By default, the search will take place in the current project:
folder__<folder_ID>, you can choose another one. -
Click Execute.
-
To open a separate trace, specify its ID in the Enter trace.id field at the top right.
For more on trace viewing and searching, see Viewing your applications' traces in Monium Traces.