|
| 1 | +#!/bin/bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +# Adjust as needed. |
| 5 | +CONFIG_FILE="/etc/boxcutter-config.json" |
| 6 | +TEXTFILE_COLLECTOR_DIR=/var/lib/node_exporter/textfile/ |
| 7 | +INPUT_JSON='/var/chef/reports/chef-run-metrics.json' |
| 8 | + |
| 9 | +# Convert ISO8601 → epoch seconds |
| 10 | +iso_to_epoch() { |
| 11 | + local ts="$1" |
| 12 | + [[ -z "$ts" || "$ts" == "null" ]] && echo "0" && return |
| 13 | + |
| 14 | + # GNU date handles ISO 8601 natively |
| 15 | + date -d "$ts" +%s 2>/dev/null || echo "0" |
| 16 | +} |
| 17 | + |
| 18 | +metrics_to_stdout() { |
| 19 | + echo "Report time (ISO 8601): ${report_time_iso8601}" |
| 20 | + echo "Report time (Unix epoch): ${report_time_unix_epoch}" |
| 21 | + echo "Success: ${success}" |
| 22 | + echo "Last success time (ISO 8601): ${last_success_time_iso8601}" |
| 23 | + echo "Last success time (Unix epoch): ${last_success_unix_epoch}" |
| 24 | + echo "Start time (ISO 8601): ${start_time_iso8601}" |
| 25 | + echo "Start time (Unix epoch): ${start_time_unix_epoch}" |
| 26 | + echo "End time (ISO 8601): ${end_time_iso8601}" |
| 27 | + echo "End time (Unix epoch): ${end_time_unix_epoch}" |
| 28 | + echo "Elapsed time (ms): ${elapsed_time_ms}" |
| 29 | + echo "All resources: ${all_resources_count}" |
| 30 | + echo "Updated resources: ${updated_resources_count}" |
| 31 | +} |
| 32 | + |
| 33 | +metrics_to_prometheus() { |
| 34 | + local tags="$1" |
| 35 | + |
| 36 | +cat << EOF > "$TEXTFILE_COLLECTOR_DIR/chef_metrics.prom.$$" |
| 37 | +# HELP chef_client_run_success Whether the last Chef run succeeded (1) or failed (0). |
| 38 | +# TYPE chef_client_run_success gauge |
| 39 | +chef_client_run_success${tags} ${success} |
| 40 | +# HELP chef_client_run_last_success_timestamp_seconds Unix timestamp of the most recent successful Chef run. |
| 41 | +# TYPE chef_client_run_last_success_timestamp_seconds gauge |
| 42 | +chef_client_run_last_success_timestamp_seconds${tags} ${last_success_unix_epoch} |
| 43 | +# HELP chef_client_run_duration_seconds Duration of the last Chef run in seconds. |
| 44 | +# TYPE chef_client_run_duration_seconds gauge |
| 45 | +chef_client_run_duration_seconds${tags} ${elapsed_seconds} |
| 46 | +# HELP chef_client_run_resources_total Total resources in the last Chef run. |
| 47 | +# TYPE chef_client_run_resources_total gauge |
| 48 | +chef_client_resources_total${tags} ${all_resources_count} |
| 49 | +# HELP chef_client_run_updated_resources_total Updated resources in the last Chef run. |
| 50 | +# TYPE chef_client_run_updated_resources_total gauge |
| 51 | +chef_client_updated_resources_total${tags} ${updated_resources_count} |
| 52 | +EOF |
| 53 | + |
| 54 | + # Rename the temporary file atomically. |
| 55 | + # This avoids the node exporter seeing half a file. |
| 56 | + mv "$TEXTFILE_COLLECTOR_DIR/chef_metrics.prom.$$" \ |
| 57 | + "$TEXTFILE_COLLECTOR_DIR/chef_metrics.prom" |
| 58 | +} |
| 59 | + |
| 60 | +# Extract fields (use //empty to avoid 'null' output and allow defaults) |
| 61 | +report_time_iso8601="$(jq -r '.report_time_iso8601 // empty' "$INPUT_JSON")" |
| 62 | +success="$(jq -r '.success // 0' "$INPUT_JSON")" |
| 63 | +last_success_time_iso8601="$(jq -r '.last_success_time_iso8601 // empty' "$INPUT_JSON")" |
| 64 | +start_time_iso8601="$(jq -r '.start_time_iso8601 // empty' "$INPUT_JSON")" |
| 65 | +end_time_iso8601="$(jq -r '.end_time_iso8601 // empty' "$INPUT_JSON")" |
| 66 | +elapsed_time_ms="$(jq -r '.elapsed_time_ms // empty' "$INPUT_JSON")" |
| 67 | +all_resources_count="$(jq -r '.all_resources_count // empty' "$INPUT_JSON")" |
| 68 | +updated_resources_count="$(jq -r '.updated_resources_count // empty' "$INPUT_JSON")" |
| 69 | + |
| 70 | +report_time_unix_epoch=$(iso_to_epoch "${report_time_iso8601}") |
| 71 | +last_success_unix_epoch="$(iso_to_epoch "${last_success_time_iso8601}")" |
| 72 | +start_time_unix_epoch="$(iso_to_epoch "$start_time_iso8601")" |
| 73 | +end_time_unix_epoch="$(iso_to_epoch "$end_time_iso8601")" |
| 74 | + |
| 75 | +elapsed_seconds="$(jq -nr --arg v "$elapsed_time_ms" '($v|tonumber) / 1000.0')" |
| 76 | + |
| 77 | +if [[ -r "$CONFIG_FILE" ]]; then |
| 78 | + tier="$(jq -r '.tier // empty' "$CONFIG_FILE")" |
| 79 | + [[ -n "$tier" ]] || tier="default" |
| 80 | +fi |
| 81 | + |
| 82 | +tags="{tier=\"$tier\"}" |
| 83 | +metrics_to_prometheus "$tags" |
0 commit comments