UNPKG

openclaw-grafana-lens

Version:

OpenClaw plugin that gives AI agents full Grafana access — 18 composable tools for PromQL/LogQL/TraceQL queries, dashboard creation, alerting, SRE investigation, security monitoring, data collection pipeline management via Grafana Alloy (29 recipes), and

81 lines (79 loc) 3.27 kB
import { AlloyConfigBuilder, componentLabel, escapeString, renderValue } from "../../config-builder.js"; import { credentialEnvVar } from "../types.js"; import { buildProcessBlock, extractProcessingParams, PROCESSING_OPTIONAL_PARAMS } from "./_process-builder.js"; const recipe = { name: "kafka-logs", category: "logs", signal: "logs", summary: "Consume logs from Apache Kafka topics with optional JSON/label processing", dashboardTemplate: null, credentialParams: ["kafkaAuth"], requiredParams: [ { name: "brokers", type: "string[]", description: "Kafka broker addresses", example: "kafka:9092" }, { name: "topics", type: "string[]", description: "Kafka topics to consume", example: "app-logs" }, ], optionalParams: [ { name: "consumerGroup", type: "string", description: "Kafka consumer group ID", default: "alloy" }, { name: "kafkaAuth", type: "string", description: "SASL credentials (user:password)", sensitive: true }, ...PROCESSING_OPTIONAL_PARAMS, ], generateConfig(pipelineId, params, targets, pipelineName) { const brokers = params.brokers; const topics = params.topics; const consumerGroup = params.consumerGroup || "alloy"; const kafkaAuth = params.kafkaAuth; const srcLabel = componentLabel(pipelineId, "kafka"); const writeLabel = componentLabel(pipelineId, "write"); const builder = new AlloyConfigBuilder(); const processing = buildProcessBlock(pipelineId, extractProcessingParams(params), `loki.write.${writeLabel}.receiver`); const forwardTo = processing ? processing.receiverRef : `loki.write.${writeLabel}.receiver`; const brokerList = renderValue(brokers); const topicList = renderValue(topics); let srcBlock = `loki.source.kafka "${srcLabel}" { brokers = [${brokerList}] topics = [${topicList}] consumer_group = "${escapeString(consumerGroup)}" forward_to = [${forwardTo}] labels = { source = "kafka" }`; if (kafkaAuth) { const userEnv = credentialEnvVar("kafka-logs", pipelineName, "kafkaAuth_user"); const passEnv = credentialEnvVar("kafka-logs", pipelineName, "kafkaAuth_pass"); srcBlock += ` authentication { type = "sasl" sasl { mechanism = "PLAIN" username = sys.env("${userEnv}") password = sys.env("${passEnv}") } }`; } srcBlock += "\n}"; builder.addBlock(srcBlock); if (processing) { builder.addBlock(processing.block); } builder.addBlock(`loki.write "${writeLabel}" { endpoint { url = "${escapeString(targets.lokiWriteUrl)}" } }`); return builder.build(pipelineId, "kafka-logs", "kafka-logs"); }, sampleQueries() { return { recentLogs: '{source="kafka"}', errorLogs: '{source="kafka"} |= "error"', logVolume: 'rate({source="kafka"}[5m])', }; }, componentIds(pipelineId) { return [ `loki.source.kafka.${componentLabel(pipelineId, "kafka")}`, `loki.write.${componentLabel(pipelineId, "write")}`, ]; }, }; export default recipe;