Files
oneuptime/Common/UI/Utils/LogExport.ts
Nawaz Dhandala 0e93929a3f feat: add LogPipelineProcessor model and related services
- Implemented LogPipelineProcessor model with necessary fields and access controls.
- Created LogDropFilterAction enum for defining actions on log drop filters.
- Introduced LogPipelineProcessorType enum and configuration interfaces for various processor types.
- Developed LogExport utility for exporting logs in CSV and JSON formats.
- Added LogDropFilterService for managing drop filters with caching.
- Implemented LogPipelineService for loading and processing log pipelines with processors.
- Created LogFilterEvaluator for evaluating filter queries against log entries.
2026-03-13 11:50:07 +00:00

161 lines
4.1 KiB
TypeScript

import Log from "../../Models/AnalyticsModels/Log";
import { JSONObject } from "../../Types/JSON";
import {
isLogsAttributeColumnId,
getLogsAttributeKeyFromColumnId,
} from "../Components/LogsViewer/types";
export enum LogExportFormat {
CSV = "csv",
JSON = "json",
}
function escapeCsvValue(value: string): string {
if (
value.includes(",") ||
value.includes('"') ||
value.includes("\n") ||
value.includes("\r")
) {
return `"${value.replace(/"/g, '""')}"`;
}
return value;
}
function getLogFieldValue(log: Log, columnId: string): string {
if (isLogsAttributeColumnId(columnId)) {
const attrKey: string | null = getLogsAttributeKeyFromColumnId(columnId);
if (attrKey && log.attributes) {
const val: unknown = (log.attributes as Record<string, unknown>)[attrKey];
if (val === undefined || val === null) {
return "";
}
if (typeof val === "object") {
return JSON.stringify(val);
}
return String(val);
}
return "";
}
switch (columnId) {
case "time":
return log.time ? new Date(log.time).toISOString() : "";
case "service":
return log.serviceId?.toString() || "";
case "severity":
return log.severityText?.toString() || "";
case "message":
return log.body || "";
case "traceId":
return log.traceId || "";
case "spanId":
return log.spanId || "";
default:
return "";
}
}
function getColumnLabel(columnId: string): string {
if (isLogsAttributeColumnId(columnId)) {
return getLogsAttributeKeyFromColumnId(columnId) || columnId;
}
switch (columnId) {
case "time":
return "Time";
case "service":
return "Service ID";
case "severity":
return "Severity";
case "message":
return "Message";
case "traceId":
return "Trace ID";
case "spanId":
return "Span ID";
default:
return columnId;
}
}
export function exportLogsToCSV(
logs: Array<Log>,
columns: Array<string>,
): string {
const header: string = columns
.map((col: string) => {
return escapeCsvValue(getColumnLabel(col));
})
.join(",");
const rows: Array<string> = logs.map((log: Log) => {
return columns
.map((col: string) => {
return escapeCsvValue(getLogFieldValue(log, col));
})
.join(",");
});
return [header, ...rows].join("\n");
}
export function exportLogsToJSON(logs: Array<Log>): string {
const data: Array<JSONObject> = logs.map((log: Log) => {
const obj: JSONObject = {};
obj["time"] = log.time ? new Date(log.time).toISOString() : null;
obj["serviceId"] = log.serviceId?.toString() || null;
obj["severity"] = log.severityText?.toString() || null;
obj["severityNumber"] = log.severityNumber || null;
obj["body"] = log.body || null;
obj["traceId"] = log.traceId || null;
obj["spanId"] = log.spanId || null;
obj["attributes"] = (log.attributes as JSONObject) || {};
return obj;
});
return JSON.stringify(data, null, 2);
}
function downloadFile(
content: string,
filename: string,
mimeType: string,
): void {
const blob: Blob = new Blob([content], { type: mimeType });
const url: string = window.URL.createObjectURL(blob);
const anchor: HTMLAnchorElement = document.createElement("a");
anchor.href = url;
anchor.download = filename;
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
window.URL.revokeObjectURL(url);
}
function getTimestampFilename(format: LogExportFormat): string {
const now: string = new Date()
.toISOString()
.replace(/[:.]/g, "-")
.slice(0, 19);
return `logs-${now}.${format}`;
}
export function exportLogs(
logs: Array<Log>,
format: LogExportFormat,
columns: Array<string>,
): void {
if (format === LogExportFormat.CSV) {
const csv: string = exportLogsToCSV(logs, columns);
downloadFile(csv, getTimestampFilename(format), "text/csv;charset=utf-8;");
} else {
const json: string = exportLogsToJSON(logs);
downloadFile(
json,
getTimestampFilename(format),
"application/json;charset=utf-8;",
);
}
}