snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
This commit is contained in:
126
internal/scripts/fetch-fly-logs.ts
Normal file
126
internal/scripts/fetch-fly-logs.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Fetch logs from Fly.io's VictoriaLogs API.
|
||||
*
|
||||
* Usage:
|
||||
* npx tsx internal/scripts/fetch-fly-logs.ts [options]
|
||||
*
|
||||
* Examples:
|
||||
* npx tsx internal/scripts/fetch-fly-logs.ts --app production-zero-rm --last 2h
|
||||
* npx tsx internal/scripts/fetch-fly-logs.ts --app production-zero-rm --last 30m --filter "Purged"
|
||||
* npx tsx internal/scripts/fetch-fly-logs.ts --app production-zero-rm --start 2026-04-15T15:00:00Z --end 2026-04-15T18:00:00Z
|
||||
* npx tsx internal/scripts/fetch-fly-logs.ts --app production-zero-rm --last 1h --filter "NOT DEBUG" -o logs.jsonl
|
||||
* npx tsx internal/scripts/fetch-fly-logs.ts --app production-zero-rm --last 6h --filter "Purged" --pretty
|
||||
* FLY_TOKEN=fo1_xxx npx tsx internal/scripts/fetch-fly-logs.ts --app production-zero-rm --last 1h
|
||||
* npx tsx internal/scripts/fetch-fly-logs.ts --token fo1_xxx --app production-zero-rm --last 1h
|
||||
*
|
||||
* See fly-common.ts for app names and token configuration.
|
||||
*/
|
||||
|
||||
import { FLY_ORG_SLUG, getFlyToken, parseDuration } from './fly-common'
|
||||
|
||||
const BASE_URL = `https://api.fly.io/victorialogs/${FLY_ORG_SLUG}/select/logsql/query`
|
||||
|
||||
function parseArgs() {
|
||||
const args = process.argv.slice(2)
|
||||
const opts: Record<string, string> = {}
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] === '--token' || args[i] === '-t') opts.token = args[++i]
|
||||
else if (args[i] === '--app' || args[i] === '-a') opts.app = args[++i]
|
||||
else if (args[i] === '--start') opts.start = args[++i]
|
||||
else if (args[i] === '--end') opts.end = args[++i]
|
||||
else if (args[i] === '--last' || args[i] === '-l') opts.last = args[++i]
|
||||
else if (args[i] === '--filter' || args[i] === '-f') opts.filter = args[++i]
|
||||
else if (args[i] === '--limit') opts.limit = args[++i]
|
||||
else if (args[i] === '--output' || args[i] === '-o') opts.output = args[++i]
|
||||
else if (args[i] === '--pretty' || args[i] === '-p') opts.pretty = 'true'
|
||||
else if (args[i] === '--help' || args[i] === '-h') {
|
||||
console.log(
|
||||
[
|
||||
'Usage: npx tsx internal/scripts/fetch-fly-logs.ts [options]',
|
||||
'',
|
||||
'Options:',
|
||||
' --token, -t Fly API token (falls back to FLY_TOKEN env var)',
|
||||
' --app, -a Fly app name (required)',
|
||||
' --last, -l Duration to look back, e.g. 30m, 2h, 1d (default: 1h)',
|
||||
' --start Start time (ISO 8601), overrides --last',
|
||||
' --end End time (ISO 8601), defaults to now',
|
||||
' --filter, -f Additional LogsQL filter, e.g. "Purged", "NOT DEBUG"',
|
||||
' --limit Max lines (default: unlimited)',
|
||||
' --output, -o Write to file instead of stdout',
|
||||
' --pretty, -p Pretty-print: timestamp + message only',
|
||||
' --help, -h Show this help',
|
||||
].join('\n')
|
||||
)
|
||||
process.exit(0)
|
||||
} else {
|
||||
console.error(`Unknown option: ${args[i]}`)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
if (!opts.app) {
|
||||
console.error('--app is required')
|
||||
process.exit(1)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const opts = parseArgs()
|
||||
|
||||
const now = new Date()
|
||||
const end = opts.end ?? now.toISOString()
|
||||
let start: string
|
||||
if (opts.start) {
|
||||
start = opts.start
|
||||
} else {
|
||||
const ms = parseDuration(opts.last ?? '1h', 'ms')
|
||||
start = new Date(now.getTime() - ms).toISOString()
|
||||
}
|
||||
|
||||
let query = `fly.app.name: ${opts.app}`
|
||||
if (opts.filter) query += ` AND ${opts.filter}`
|
||||
|
||||
const params = new URLSearchParams({ query, start, end })
|
||||
if (opts.limit) params.set('limit', opts.limit)
|
||||
|
||||
const token = getFlyToken(opts.token)
|
||||
const url = `${BASE_URL}?${params}`
|
||||
|
||||
const res = await fetch(url, { headers: { Authorization: `FlyV1 ${token}` } })
|
||||
if (!res.ok) {
|
||||
console.error(`HTTP ${res.status}: ${await res.text()}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const body = await res.text()
|
||||
if (!body.trim()) {
|
||||
console.error('No logs found.')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
let output: string
|
||||
if (opts.pretty) {
|
||||
output = body
|
||||
.trim()
|
||||
.split('\n')
|
||||
.map((line) => {
|
||||
const entry = JSON.parse(line)
|
||||
return `${entry._time} ${entry._msg}`
|
||||
})
|
||||
.sort()
|
||||
.join('\n')
|
||||
} else {
|
||||
output = body
|
||||
}
|
||||
|
||||
if (opts.output) {
|
||||
const fs = await import('fs')
|
||||
fs.writeFileSync(opts.output, output + '\n')
|
||||
const lines = output.trim().split('\n').length
|
||||
console.error(`Wrote ${lines} lines to ${opts.output}`)
|
||||
} else {
|
||||
process.stdout.write(output + '\n')
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user