Skip to content

Commit 07538da

Browse files
lucaspimentelclaude
andcommitted
Add PowerShell script for querying Datadog logs
Adds Get-DatadogLogs.ps1 helper script to simplify querying logs from the Datadog Logs API. The script supports multiple output formats (table, json, raw) and follows the same pattern as the existing Get-DatadogTrace.ps1 script. Updates QueryingDatadogAPIs.md documentation with comprehensive usage examples and parameter descriptions for the new script. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 9ef1991 commit 07538da

File tree

2 files changed

+212
-1
lines changed

2 files changed

+212
-1
lines changed

docs/development/QueryingDatadogAPIs.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ This script retrieves all spans for a given trace ID and displays them in variou
238238

239239
## Logs Search API
240240

241-
### Search for logs with specific criteria
241+
### Search for logs with specific criteria (curl)
242242

243243
```bash
244244
curl -s -X POST https://api.datadoghq.com/api/v2/logs/events/search \
@@ -260,6 +260,68 @@ curl -s -X POST https://api.datadoghq.com/api/v2/logs/events/search \
260260

261261
**Note:** Unlike the Spans API, the Logs API does not require the `{"data": {"attributes": {...}, "type": "search_request"}}` wrapper structure. The request body is directly the filter/sort/page configuration.
262262

263+
## PowerShell Helper Script - Logs
264+
265+
The repository includes a PowerShell script that simplifies querying logs from the Datadog API.
266+
267+
### Get-DatadogLogs.ps1
268+
269+
**Location**: `tracer/tools/Get-DatadogLogs.ps1`
270+
271+
This script retrieves logs matching a query and displays them in various formats.
272+
273+
**Prerequisites:**
274+
- Set environment variables: `DD_API_KEY` and `DD_APPLICATION_KEY`
275+
- API keys can be obtained from https://app.datadoghq.com/organization-settings/api-keys
276+
277+
**Basic usage:**
278+
```powershell
279+
.\tracer\tools\Get-DatadogLogs.ps1 -Query "service:my-service error"
280+
```
281+
282+
**Parameters:**
283+
- `-Query` (required) - Log query using Datadog query syntax (e.g., "service:my-service error")
284+
- `-TimeRange` (optional) - How far back to search (default: "1h"). Examples: "15m", "1h", "2h", "1d"
285+
- `-Limit` (optional) - Maximum number of log entries to return (default: 50, max: 1000)
286+
- `-OutputFormat` (optional) - Output format: "table" (default), "json", or "raw"
287+
288+
**Output formats:**
289+
290+
1. **Table** (default) - Formatted table with key log information:
291+
```powershell
292+
.\tracer\tools\Get-DatadogLogs.ps1 -Query "service:my-service error"
293+
```
294+
Shows: Timestamp, Status, Service, Host, Message (truncated to 100 chars)
295+
296+
2. **JSON** - Raw JSON output for further processing:
297+
```powershell
298+
.\tracer\tools\Get-DatadogLogs.ps1 -Query "service:my-service" -OutputFormat json
299+
```
300+
301+
3. **Raw** - Simple timestamp and message format:
302+
```powershell
303+
.\tracer\tools\Get-DatadogLogs.ps1 -Query "service:my-service" -OutputFormat raw
304+
```
305+
306+
**Example workflows:**
307+
308+
1. Search for recent errors in a service:
309+
```powershell
310+
.\tracer\tools\Get-DatadogLogs.ps1 -Query "service:my-service error" -TimeRange "1h" -Limit 20
311+
```
312+
313+
2. Find tracer debug logs from Azure Functions:
314+
```powershell
315+
.\tracer\tools\Get-DatadogLogs.ps1 -Query "service:lucasp-premium-linux-isolated AspNetCoreDiagnosticObserver" -TimeRange "30m"
316+
```
317+
318+
3. Export logs as JSON for processing:
319+
```powershell
320+
.\tracer\tools\Get-DatadogLogs.ps1 -Query "service:my-service DD-TRACE-DOTNET" -OutputFormat json | ConvertFrom-Json | ConvertTo-Json -Depth 10
321+
```
322+
323+
**Note**: The script uses `Invoke-RestMethod` which properly handles authentication headers, avoiding the shell variable substitution issues that can occur with curl.
324+
263325
### Search for tracer debug logs
264326

265327
```bash

tracer/tools/Get-DatadogLogs.ps1

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<#
2+
.SYNOPSIS
3+
Retrieves logs from the Datadog Logs API.
4+
5+
.DESCRIPTION
6+
Queries the Datadog Logs API to retrieve logs matching a specific query.
7+
Requires DD_API_KEY and DD_APPLICATION_KEY environment variables to be set.
8+
9+
.PARAMETER Query
10+
The log query to search for (e.g., "service:my-service error")
11+
12+
.PARAMETER TimeRange
13+
How far back to search for logs. Defaults to "1h" (1 hour).
14+
Examples: "15m", "1h", "2h", "1d"
15+
16+
.PARAMETER Limit
17+
Maximum number of log entries to return (default: 50, max: 1000)
18+
19+
.PARAMETER OutputFormat
20+
Output format: "table" (default), "json", or "raw"
21+
22+
.EXAMPLE
23+
.\Get-DatadogLogs.ps1 -Query "service:lucasp-premium-linux-isolated AspNetCoreDiagnosticObserver"
24+
25+
.EXAMPLE
26+
.\Get-DatadogLogs.ps1 -Query "service:my-app error" -TimeRange "2h" -Limit 100
27+
28+
.EXAMPLE
29+
.\Get-DatadogLogs.ps1 -Query "service:my-app" -OutputFormat json | ConvertFrom-Json | ConvertTo-Json -Depth 10
30+
#>
31+
32+
[CmdletBinding()]
33+
param(
34+
[Parameter(Mandatory = $true, Position = 0)]
35+
[string]$Query,
36+
37+
[Parameter(Mandatory = $false)]
38+
[string]$TimeRange = "1h",
39+
40+
[Parameter(Mandatory = $false)]
41+
[int]$Limit = 50,
42+
43+
[Parameter(Mandatory = $false)]
44+
[ValidateSet("table", "json", "raw")]
45+
[string]$OutputFormat = "table"
46+
)
47+
48+
# Check for required environment variables
49+
$apiKey = $env:DD_API_KEY
50+
$appKey = $env:DD_APPLICATION_KEY
51+
52+
if ([string]::IsNullOrEmpty($apiKey)) {
53+
Write-Error "DD_API_KEY environment variable is not set. Please set it before running this script."
54+
exit 1
55+
}
56+
57+
if ([string]::IsNullOrEmpty($appKey)) {
58+
Write-Error "DD_APPLICATION_KEY environment variable is not set. Please set it before running this script."
59+
exit 1
60+
}
61+
62+
# Build the request
63+
$uri = "https://api.datadoghq.com/api/v2/logs/events/search"
64+
$headers = @{
65+
"DD-API-KEY" = $apiKey
66+
"DD-APPLICATION-KEY" = $appKey
67+
"Content-Type" = "application/json"
68+
}
69+
70+
$body = @{
71+
filter = @{
72+
query = $Query
73+
from = "now-$TimeRange"
74+
to = "now"
75+
}
76+
sort = "timestamp"
77+
page = @{
78+
limit = $Limit
79+
}
80+
} | ConvertTo-Json -Depth 10
81+
82+
Write-Verbose "Querying Datadog Logs API with query: $Query"
83+
Write-Verbose "Time range: now-$TimeRange to now"
84+
Write-Verbose "Limit: $Limit"
85+
86+
try {
87+
$response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $body -ErrorAction Stop
88+
89+
if ($null -eq $response.data -or $response.data.Count -eq 0) {
90+
Write-Warning "No logs found for query: $Query"
91+
Write-Warning "Make sure the query is correct and logs exist within the time range (now-$TimeRange to now)"
92+
exit 0
93+
}
94+
95+
$logs = $response.data | ForEach-Object {
96+
$attrs = $_.attributes
97+
98+
[PSCustomObject]@{
99+
Timestamp = $attrs.timestamp
100+
Status = $attrs.status
101+
Service = $attrs.service
102+
Message = $attrs.message
103+
Host = $attrs.host
104+
Tags = $attrs.tags -join ", "
105+
}
106+
}
107+
108+
switch ($OutputFormat) {
109+
"table" {
110+
Write-Host "`nFound $($logs.Count) log entries:" -ForegroundColor Green
111+
Write-Host "Query: $Query`n" -ForegroundColor Cyan
112+
113+
$logs | Format-Table -Property @(
114+
@{Label = "Timestamp"; Expression = {
115+
$dt = [DateTime]::Parse($_.Timestamp)
116+
$dt.ToString("yyyy-MM-dd HH:mm:ss.fff")
117+
}; Width = 23 }
118+
@{Label = "Status"; Expression = { $_.Status }; Width = 8 }
119+
@{Label = "Service"; Expression = { $_.Service }; Width = 30 }
120+
@{Label = "Host"; Expression = { $_.Host }; Width = 20 }
121+
@{Label = "Message"; Expression = {
122+
if ($_.Message.Length -gt 100) {
123+
$_.Message.Substring(0, 97) + "..."
124+
} else {
125+
$_.Message
126+
}
127+
}; Width = 100 }
128+
) -AutoSize -Wrap
129+
}
130+
"json" {
131+
$logs | ConvertTo-Json -Depth 10
132+
}
133+
"raw" {
134+
$logs | ForEach-Object {
135+
$dt = [DateTime]::Parse($_.Timestamp)
136+
$ts = $dt.ToString("yyyy-MM-dd HH:mm:ss.fff")
137+
Write-Host "$ts [$($_.Status)] $($_.Service) - $($_.Message)"
138+
}
139+
}
140+
}
141+
142+
} catch {
143+
Write-Error "Failed to query Datadog Logs API: $_"
144+
Write-Error $_.Exception.Message
145+
if ($_.ErrorDetails.Message) {
146+
Write-Error "API Response: $($_.ErrorDetails.Message)"
147+
}
148+
exit 1
149+
}

0 commit comments

Comments
 (0)