use clap::{Parser, Subcommand, ValueEnum};
use datadog::{
DatadogClient, DatadogResource, EventEntry, EventsQuery, LogEntry, LogsQuery,
format_event_entry, format_log_entry, parse_datadog_url,
};
#[derive(Debug, Clone, Copy, Default, ValueEnum)]
enum OutputFormat {
#[default]
Text,
Json,
}
#[derive(Parser)]
#[command(name = "datadog")]
#[command(version, about, long_about = None)]
struct Cli {
url: Option<String>,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand)]
enum Commands {
Logs {
query: String,
#[arg(long, default_value = "now-15m")]
from: String,
#[arg(long, default_value = "now")]
to: String,
#[arg(long, default_value = "100")]
limit: u32,
#[arg(short, long, value_enum, default_value = "text")]
output: OutputFormat,
},
Events {
query: String,
#[arg(long, default_value = "now-15m")]
from: String,
#[arg(long, default_value = "now")]
to: String,
#[arg(long, default_value = "100")]
limit: u32,
#[arg(short, long, value_enum, default_value = "text")]
output: OutputFormat,
},
}
fn get_client() -> DatadogClient {
match DatadogClient::new() {
Ok(c) => c,
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
}
fn print_log_entry(entry: &LogEntry, output: OutputFormat) {
match output {
OutputFormat::Text => println!("{}", format_log_entry(entry)),
OutputFormat::Json => println!("{}", serde_json::to_string(entry).unwrap()),
}
}
fn print_event_entry(entry: &EventEntry, output: OutputFormat) {
match output {
OutputFormat::Text => println!("{}", format_event_entry(entry)),
OutputFormat::Json => println!("{}", serde_json::to_string(entry).unwrap()),
}
}
fn run_logs_query(query: &LogsQuery, output: OutputFormat) {
let client = get_client();
match client.search_logs(query, |batch| {
for entry in batch {
print_log_entry(entry, output);
}
}) {
Ok(0) => {
eprintln!("No logs found for query: {}", query.query);
}
Ok(_) => {}
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
}
fn run_events_query(query: &EventsQuery, output: OutputFormat) {
let client = get_client();
match client.search_events(query, |batch| {
for entry in batch {
print_event_entry(entry, output);
}
}) {
Ok(0) => {
eprintln!("No events found for query: {}", query.query);
}
Ok(_) => {}
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
}
fn main() {
let cli = Cli::parse();
if let Some(url_str) = cli.url {
match parse_datadog_url(&url_str) {
Ok(DatadogResource::Logs(query)) => {
run_logs_query(&query, OutputFormat::Text);
}
Ok(DatadogResource::Events(query)) => {
run_events_query(&query, OutputFormat::Text);
}
Err(e) => {
eprintln!("Error parsing URL: {}", e);
std::process::exit(1);
}
}
return;
}
match cli.command {
Some(Commands::Logs {
query,
from,
to,
limit,
output,
}) => {
let limit = if limit == 0 { None } else { Some(limit) };
run_logs_query(&LogsQuery::new(query, from, to, limit), output);
}
Some(Commands::Events {
query,
from,
to,
limit,
output,
}) => {
let limit = if limit == 0 { None } else { Some(limit) };
run_events_query(&EventsQuery::new(query, from, to, limit), output);
}
None => {
eprintln!("Error: No URL or command provided. Use --help for usage information.");
std::process::exit(1);
}
}
}