Files
LokiStack/backend/services/collector_templates.go
T
Logan.LiandClaude 673b2c60c8 feat: 新增「部署客户端」日志采集器模块
三种采集器(host-promtail / k8s-daemonset / k8s-fluentbit-sidecar),每种关联已部署 Loki:
- host-promtail:SSH 安装 Promtail(复用 deployBinary)
- k8s-daemonset:helm 安装 Promtail DaemonSet(复用 deployHelm)
- k8s-fluentbit-sidecar:kubectl patch 注入 Fluent Bit sidecar

含 Collector 数据模型、三个部署器、配置模板、CRUD API、前端页面。
附带 UI 优化:ErrorBoundary、部署卡片浏览器访问按钮、菜单名称调整。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-29 19:26:41 +08:00

184 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package services
import (
"fmt"
"strings"
)
// PromtailConfig 主机 Promtail 配置(推送至 lokiEndpoint,采集 logPath)
func PromtailConfig(lokiEndpoint, logPath string) string {
return fmt.Sprintf(`server:
http_listen_port: 9080
grpc_listen_port: 0
log_level: info
positions:
filename: /tmp/positions.yaml
clients:
- url: %s/loki/api/v1/push
scrape_configs:
- job_name: app
static_configs:
- targets: [localhost]
labels:
job: app
host: ${HOSTNAME}
__path__: %s
`, lokiEndpoint, logPath)
}
// PromtailHelmValues DaemonSet 模式 Promtail Helm values
func PromtailHelmValues(lokiEndpoint string) string {
return fmt.Sprintf(`config:
clients:
- url: %s/loki/api/v1/push
daemonset:
enabled: true
serviceAccount:
create: true
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
extraVolumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
extraVolumeMounts:
- name: varlog
mountPath: /var/log
readOnly: true
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
`, lokiEndpoint)
}
// FluentbitConfig Sidecar 模式 Fluent Bit 配置(采集 logPath,推送至 lokiHost:lokiPort)
func FluentbitConfig(lokiHost, lokiPort, logPath, app, namespace string) string {
return fmt.Sprintf(`[SERVICE]
Flush 5
Log_Level info
HTTP_Server On
HTTP_Listen 0.0.0.0
HTTP_Port 2020
[INPUT]
Name tail
Path %s
Tag app.%s
Refresh_Interval 5
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Read_from_Head True
DB /tmp/flb.db
[FILTER]
Name modify
Match app.*
Add namespace %s
Add app %s
[OUTPUT]
Name loki
Match *
Host %s
Port %s
Labels job=fluent-bit, app=%s, namespace=%s
`, logPath, app, namespace, app, lokiHost, lokiPort, app, namespace)
}
// FluentbitConfigMapYAML 包装 fluent-bit.conf 为 ConfigMap YAML(部署到 namespace)
func FluentbitConfigMapYAML(conf, namespace string) string {
return fmt.Sprintf(`apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: %s
data:
fluent-bit.conf: |
%s
`, namespace, indentBlock(conf, " "))
}
// SidecarPatchYAML strategic merge patch:为 Deployment 注入 Fluent Bit sidecar 容器
const SidecarPatchYAML = `spec:
template:
spec:
volumes:
- name: app-logs
emptyDir: {}
- name: fluent-bit-config
configMap:
name: fluent-bit-config
containers:
- name: fluent-bit
image: cr.fluentbit.io/fluent/fluent-bit:3.1.1
imagePullPolicy: IfNotPresent
volumeMounts:
- name: app-logs
mountPath: /var/log/app
readOnly: true
- name: fluent-bit-config
mountPath: /fluent-bit/etc/
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
`
// SidecarRemovePatchYAML strategic merge patch:从 Deployment 移除 Fluent Bit sidecar(卸载)
const SidecarRemovePatchYAML = `spec:
template:
spec:
containers:
- name: fluent-bit
$patch: delete
volumes:
- name: app-logs
$patch: delete
- name: fluent-bit-config
$patch: delete
`
// indentBlock 给每行加前缀(ConfigMap 嵌入配置需缩进)
func indentBlock(s, pad string) string {
lines := strings.Split(s, "\n")
for i, l := range lines {
if l != "" {
lines[i] = pad + l
}
}
return strings.Join(lines, "\n")
}
// parseLokiURL 从 http://host:port 提取 host 与 port(Fluent Bit OUTPUT 需要)
func parseLokiURL(endpoint string) (host, port string) {
u := strings.TrimSpace(endpoint)
u = strings.TrimPrefix(u, "http://")
u = strings.TrimPrefix(u, "https://")
if i := strings.Index(u, "/"); i >= 0 {
u = u[:i]
}
if i := strings.LastIndex(u, ":"); i >= 0 {
return u[:i], u[i+1:]
}
return u, "3100"
}