diff --git a/homepage/assets/screenshots/alerts.png b/homepage/assets/screenshots/alerts.png new file mode 100644 index 0000000..1cd0861 Binary files /dev/null and b/homepage/assets/screenshots/alerts.png differ diff --git a/homepage/assets/screenshots/analysis.png b/homepage/assets/screenshots/analysis.png new file mode 100644 index 0000000..bf97022 Binary files /dev/null and b/homepage/assets/screenshots/analysis.png differ diff --git a/homepage/assets/screenshots/dashboard.png b/homepage/assets/screenshots/dashboard.png new file mode 100644 index 0000000..41824fc Binary files /dev/null and b/homepage/assets/screenshots/dashboard.png differ diff --git a/homepage/assets/screenshots/logs-query.png b/homepage/assets/screenshots/logs-query.png new file mode 100644 index 0000000..4a31a65 Binary files /dev/null and b/homepage/assets/screenshots/logs-query.png differ diff --git a/homepage/assets/screenshots/settings.png b/homepage/assets/screenshots/settings.png new file mode 100644 index 0000000..e400d08 Binary files /dev/null and b/homepage/assets/screenshots/settings.png differ diff --git a/homepage/assets/screenshots/wizard.png b/homepage/assets/screenshots/wizard.png new file mode 100644 index 0000000..9bee585 Binary files /dev/null and b/homepage/assets/screenshots/wizard.png differ diff --git a/homepage/dist/assets/site.css b/homepage/dist/assets/site.css new file mode 100644 index 0000000..ad537a5 --- /dev/null +++ b/homepage/dist/assets/site.css @@ -0,0 +1,58 @@ +:root { + --brand: #059669; --brand-dark: #047857; --ink: #0f172a; --muted: #64748b; + --bg: #f8fafc; --card: #ffffff; --line: #e2e8f0; + --code-bg: #0f172a; --code-ink: #e2e8f0; +} +* { margin: 0; padding: 0; box-sizing: border-box; } +html { scroll-behavior: smooth; } +body { font-family: -apple-system, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif; color: var(--ink); background: var(--bg); line-height: 1.7; } +a { color: var(--brand); text-decoration: none; } +.container { max-width: 1080px; margin: 0 auto; padding: 0 24px; } + +.nav { position: sticky; top: 0; z-index: 10; background: rgba(255,255,255,.92); backdrop-filter: blur(8px); border-bottom: 1px solid var(--line); } +.nav-inner { max-width: 1080px; margin: 0 auto; padding: 14px 24px; display: flex; align-items: center; justify-content: space-between; } +.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 20px; color: var(--ink); } +.brand-logo { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 9px; background: linear-gradient(135deg, #10b981, #047857); color: #fff; font-weight: 800; } +.nav-links { display: flex; gap: 26px; font-size: 15px; } +.nav-links a { color: var(--muted); } +.nav-links a:hover { color: var(--ink); } + +.hero { padding: 96px 0 84px; text-align: center; background: radial-gradient(1200px 500px at 50% -100px, rgba(16,185,129,.12), transparent); } +.hero h1 { font-size: 46px; line-height: 1.25; letter-spacing: -1px; } +.hero h1 em { font-style: normal; color: var(--brand); } +.hero p.tagline { margin: 18px auto 0; max-width: 640px; font-size: 19px; color: var(--muted); } +.hero-actions { margin-top: 34px; display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; } +.btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 26px; border-radius: 10px; font-size: 16px; font-weight: 600; border: 1px solid transparent; transition: all .15s; } +.btn-primary { background: var(--brand); color: #fff; } +.btn-primary:hover { background: var(--brand-dark); } +.btn-outline { border-color: var(--line); color: var(--ink); background: var(--card); } +.btn-outline:hover { border-color: var(--brand); color: var(--brand); } +.hero-meta { margin-top: 26px; font-size: 14px; color: var(--muted); } + +section.block { padding: 72px 0; } +section.block.alt { background: var(--card); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); } +.block h2 { font-size: 30px; text-align: center; } +.block .sub { text-align: center; color: var(--muted); margin-top: 10px; margin-bottom: 44px; } + +.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; } +.feature { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 26px; } +.feature .icon { width: 42px; height: 42px; border-radius: 10px; display: flex; align-items: center; justify-content: center; background: rgba(16,185,129,.1); color: var(--brand); margin-bottom: 14px; } +.feature h3 { font-size: 17px; margin-bottom: 8px; } +.feature p { font-size: 14.5px; color: var(--muted); } + +.steps { max-width: 760px; margin: 0 auto; } +.step { display: flex; gap: 18px; padding: 18px 0; border-bottom: 1px dashed var(--line); } +.step:last-child { border-bottom: none; } +.step .no { flex-shrink: 0; width: 34px; height: 34px; border-radius: 50%; background: var(--brand); color: #fff; font-weight: 700; display: flex; align-items: center; justify-content: center; } +.step h3 { font-size: 16px; } +.step p { font-size: 14.5px; color: var(--muted); margin-top: 4px; } +code.inline { background: rgba(16,185,129,.08); color: var(--brand-dark); padding: 2px 7px; border-radius: 5px; font-size: 13.5px; font-family: ui-monospace, "SF Mono", Menlo, monospace; } + +.footer { padding: 40px 0 56px; color: var(--muted); font-size: 14px; text-align: center; } +.footer .links { display: flex; gap: 22px; justify-content: center; margin-bottom: 14px; } + +@media (max-width: 840px) { + .grid { grid-template-columns: 1fr; } + .hero h1 { font-size: 34px; } + .nav-links { display: none; } +} diff --git a/homepage/dist/docs/access/index.html b/homepage/dist/docs/access/index.html new file mode 100644 index 0000000..376d51a --- /dev/null +++ b/homepage/dist/docs/access/index.html @@ -0,0 +1,33 @@ + + + +查询授权 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

查询授权

+
采集与查询 · 更新于 2026-10-28
+

管理员在「日志查询 → 查询授权」用策略组控制普通用户可见的日志范围:

+ +

用户管理(仅管理员)支持创建/重置密码/批量删除;LDAP 用户可在系统设置接入后导入。

+ +
+ +
+ + diff --git a/homepage/dist/docs/alerts/index.html b/homepage/dist/docs/alerts/index.html new file mode 100644 index 0000000..404e393 --- /dev/null +++ b/homepage/dist/docs/alerts/index.html @@ -0,0 +1,48 @@ + + + +告警通知 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

告警通知

+
告警与运维 · 更新于 2026-10-28
+

「日志告警」页(/alerts)管理规则、通知通道与发送历史。

+

告警通知

+

快速开始

+
    +
  1. 在「通知通道」中编辑默认通道,填入飞书群机器人 Webhook 并启用。
  2. +
  3. 内置九条规则默认启用并已绑定默认通道,命中阈值即发送到群。
  4. +
+

规则

+ +

通道与发送历史

+ +

防刷屏机制

+ + +
+ +
+ + diff --git a/homepage/dist/docs/analysis/index.html b/homepage/dist/docs/analysis/index.html new file mode 100644 index 0000000..6697567 --- /dev/null +++ b/homepage/dist/docs/analysis/index.html @@ -0,0 +1,84 @@ + + + +日志分析 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

日志分析

+
采集与查询 · 更新于 2026-10-28
+

「日志分析」页(/analysis,管理员)自动聚合日志指标,无需手动查询:

+

日志分析

+ +

数据来源与耗时

+ + + + + + + + + + + + + + + + + + + + + + + + + +
数据来源耗时
总量/体积趋势、总条数Loki 索引接口(index/volume_range、index/stats),只读 chunk 元数据百毫秒级
≤1 小时范围的应用排行实时扫描日志内容(count_over_time)5 分钟窗口约 5~10 秒
>1 小时范围的应用排行平台按小时预聚合快照(每小时第 5 分钟抓上一个完整小时)毫秒级
+
+

一次分析页要跑多条按应用的重查询,因此筛选栏改条件后点「刷新」才生效;
+应用排行卡片滚动到可视区才发起重查询,避免首屏一起等。

+
+

应用排行的「体积」口径

+

预聚合快照对每个应用每小时同时留存 条数 + 体积:

+ +

体积优先排序的原因:条数会被高频短日志主导(一条 INFO 刷屏 vs 一条大 JSON),
+用户真正关心的是「哪个应用把日志量吃掉了」。

+

体积列上线前抓的小时只有条数,页面会在表格下方提示
+「其中 N/M 小时有体积数据…」——不要把这个提示当成故障,
+它是在说明这段时间的体积偏小是采样口径问题,而不是应用体积真的小。

+

每日日志量的「未留存」

+

每日量来自平台自己的留存库(默认保留 400 天),不受 Loki retention(72 小时)限制。

+ +

时间范围与数据源在页面顶部切换;指标查询经服务端聚合,开销远低于拉取原始日志。

+ +
+ +
+ + diff --git a/homepage/dist/docs/assets/docs.css b/homepage/dist/docs/assets/docs.css new file mode 100644 index 0000000..28649df --- /dev/null +++ b/homepage/dist/docs/assets/docs.css @@ -0,0 +1,255 @@ +/* OpsxAPI 文档站 —— 清爽专业风格(浅色) */ +:root { + --blue: #059669; + --blue-dark: #047857; + --blue-soft: rgba(5, 150, 105, 0.08); + --bg: #f6f8fb; + --panel: #ffffff; + --border: #e4e9f1; + --text: #1c2434; + --text-2: #5b6880; + --text-3: #98a2b3; + --code-bg: #f3f6fb; + --code-border: #e1e8f3; + --green: #059669; + --amber: #b45309; + --red: #dc2626; + --sidebar-w: 262px; + --toc-w: 220px; + --topbar-h: 56px; + --radius: 10px; + --shadow: 0 1px 3px rgba(16, 24, 40, 0.06), 0 8px 24px rgba(16, 24, 40, 0.05); + --mono: "JetBrains Mono", SFMono-Regular, Menlo, Consolas, monospace; +} +* { box-sizing: border-box; } +html { scroll-behavior: smooth; scroll-padding-top: 72px; } +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif; + background: var(--bg); + color: var(--text); + font-size: 14.5px; + line-height: 1.75; +} +a { color: var(--blue); text-decoration: none; } +.i { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vertical-align: -2px; } +a:hover { color: var(--blue-dark); text-decoration: underline; } + +/* ---------- 顶栏 ---------- */ +.topbar { + position: sticky; top: 0; z-index: 50; + background: rgba(255, 255, 255, 0.92); + backdrop-filter: saturate(1.4) blur(8px); + border-bottom: 1px solid var(--border); +} +.topbar-inner { + max-width: 1440px; margin: 0 auto; height: var(--topbar-h); + display: flex; align-items: center; gap: 14px; padding: 0 20px; +} +.menu-btn { + display: none; border: 1px solid var(--border); background: #fff; + border-radius: 8px; width: 34px; height: 34px; cursor: pointer; color: var(--text-2); + place-items: center; +} +.menu-btn .i { width: 17px; height: 17px; } +.brand { display: flex; align-items: center; gap: 9px; text-decoration: none !important; } +.brand-logo { display: inline-flex; } +.brand-logo svg { display: block; border-radius: 7px; } +.brand-name { font-size: 16px; font-weight: 700; color: var(--text); } +.brand-name em { font-style: normal; font-weight: 500; color: var(--text-2); margin-left: 2px; } +.ver-badge { + font-size: 11px; font-weight: 600; color: var(--blue); + background: var(--blue-soft); border: 1px solid rgba(5, 150, 105, 0.22); + padding: 1px 9px; border-radius: 999px; white-space: nowrap; +} +.search { position: relative; flex: 1; max-width: 420px; margin-left: 8px; } +.search input { + width: 100%; height: 36px; border: 1px solid var(--border); border-radius: 9px; + background: var(--bg); padding: 0 14px 0 34px; font-size: 13.5px; color: var(--text); outline: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%2398a2b3' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E"); + background-repeat: no-repeat; background-position: 12px center; +} +.search input:focus { border-color: var(--blue); background: #fff; box-shadow: 0 0 0 3px var(--blue-soft); } +.search-panel { + position: absolute; top: 44px; left: 0; right: 0; background: #fff; + border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); + max-height: 420px; overflow: auto; padding: 6px; +} +.search-item { display: block; padding: 8px 12px; border-radius: 8px; text-decoration: none !important; } +.search-item:hover, .search-item.sel { background: var(--blue-soft); } +.search-item .si-title { font-weight: 600; color: var(--text); font-size: 13.5px; } +.search-item .si-group { color: var(--text-3); font-size: 11px; margin-left: 6px; } +.search-item .si-snippet { color: var(--text-2); font-size: 12px; margin-top: 2px; display: block; } +.search-empty { padding: 14px; text-align: center; color: var(--text-3); font-size: 13px; } +.top-links { margin-left: auto; display: flex; gap: 16px; align-items: center; } +.top-links a { font-size: 13.5px; font-weight: 500; } + +/* ---------- 三栏布局 ---------- */ +.layout { + max-width: 1440px; margin: 0 auto; display: grid; + grid-template-columns: var(--sidebar-w) minmax(0, 1fr) var(--toc-w); + gap: 0 28px; padding: 24px 20px 60px; +} + +/* 侧栏 */ +.sidebar { position: sticky; top: calc(var(--topbar-h) + 24px); align-self: start; max-height: calc(100vh - var(--topbar-h) - 48px); overflow-y: auto; padding-right: 8px; } +.sidebar::-webkit-scrollbar { width: 4px; } +.sidebar::-webkit-scrollbar-thumb { background: #d6dde8; border-radius: 4px; } +.nav-group { margin-bottom: 18px; } +.nav-group-title { + font-size: 11.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; + color: var(--text-3); padding: 0 10px 6px; +} +.nav-link { + display: block; padding: 6px 10px; border-radius: 8px; font-size: 13.5px; + color: var(--text-2); text-decoration: none !important; border-left: 2px solid transparent; +} +.nav-link:hover { background: rgba(5, 150, 105, 0.06); color: var(--text); } +.nav-link.active { + background: var(--blue-soft); color: var(--blue-dark); font-weight: 600; + border-left-color: var(--blue); +} +.sidebar-foot { margin-top: 24px; padding: 12px 10px 0; border-top: 1px solid var(--border); font-size: 11.5px; color: var(--text-3); } + +/* 内容 */ +.content { min-width: 0; max-width: 860px; } +.breadcrumb { font-size: 12.5px; color: var(--text-3); margin-bottom: 10px; } +.breadcrumb span { margin: 0 6px; } +.page-title { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 6px; line-height: 1.3; } +.page-meta { font-size: 12.5px; color: var(--text-3); margin-bottom: 22px; } + +/* Markdown 排版 */ +.md h2 { font-size: 21px; font-weight: 700; margin: 38px 0 12px; padding-top: 8px; letter-spacing: -0.01em; } +.md h3 { font-size: 16.5px; font-weight: 700; margin: 26px 0 8px; } +.md h2 + h3, .md h1 + h2 { margin-top: 18px; } +.md p { margin: 10px 0; color: #2a3348; } +.md ul, .md ol { padding-left: 22px; margin: 10px 0; } +.md li { margin: 5px 0; color: #2a3348; } +.md li::marker { color: var(--blue); } +.md strong { color: var(--text); } +.md hr { border: none; border-top: 1px solid var(--border); margin: 30px 0; } +.md img { max-width: 100%; border-radius: var(--radius); border: 1px solid var(--border); } +.md blockquote { + margin: 14px 0; padding: 10px 16px; border-left: 3px solid var(--blue); + background: var(--blue-soft); border-radius: 0 8px 8px 0; color: #33415e; +} + +/* 表格 */ +.md table { border-collapse: collapse; width: 100%; margin: 16px 0; font-size: 13.5px; background: #fff; border-radius: var(--radius); overflow: hidden; box-shadow: 0 0 0 1px var(--border); } +.md th, .md td { padding: 9px 14px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; } +.md th { background: #f9fbfe; font-weight: 600; color: var(--text); white-space: nowrap; } +.md tr:last-child td { border-bottom: none; } + +/* 代码块 */ +.md code { font-family: var(--mono); font-size: 12.8px; background: var(--code-bg); border: 1px solid var(--code-border); border-radius: 5px; padding: 1px 6px; color: #334155; } +.md pre { + position: relative; background: #0f172a; color: #dbe4f3; border-radius: var(--radius); + padding: 16px 16px 14px; overflow-x: auto; margin: 16px 0; font-size: 13px; line-height: 1.65; +} +.md pre code { background: none; border: none; color: inherit; padding: 0; font-size: inherit; } +.md pre .lang-tag { + position: absolute; top: 8px; right: 12px; font-size: 10.5px; color: #7c8db0; + font-family: var(--mono); text-transform: lowercase; letter-spacing: 0.04em; +} +.md pre .copy-btn { + position: absolute; top: 6px; right: 60px; font-size: 11px; color: #9fb0d0; + background: rgba(255, 255, 255, 0.07); border: none; border-radius: 6px; padding: 2px 9px; cursor: pointer; + opacity: 0; transition: opacity 0.15s; +} +.md pre:hover .copy-btn { opacity: 1; } +.md pre .copy-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.14); } +/* 行内高亮 token */ +.md pre .tok-key { color: #7dd3fc; } +.md pre .tok-str { color: #86efac; } +.md pre .tok-num { color: #fcd34d; } +.md pre .tok-com { color: #64748b; font-style: italic; } + +/* 提示块(通过 blockquote 首字符约定) */ +.md blockquote.tip { border-left-color: var(--green); background: rgba(5, 150, 105, 0.07); } +.md blockquote.warn { border-left-color: var(--amber); background: rgba(180, 83, 9, 0.07); } + +/* 上下页 */ +.pn-nav { display: flex; gap: 14px; margin-top: 48px; } +.pn { + flex: 1; border: 1px solid var(--border); background: #fff; border-radius: var(--radius); + padding: 13px 16px; text-decoration: none !important; transition: border-color 0.15s, box-shadow 0.15s; +} +.pn:hover { border-color: var(--blue); box-shadow: var(--shadow); } +.pn.next { text-align: right; } +.pn-label { display: block; font-size: 11.5px; color: var(--text-3); } +.pn-title { display: block; font-weight: 600; color: var(--text); font-size: 14px; margin-top: 2px; } + +/* 右侧目录 */ +.toc { position: sticky; top: calc(var(--topbar-h) + 24px); align-self: start; max-height: calc(100vh - var(--topbar-h) - 48px); overflow-y: auto; padding-top: 34px; } +.toc-title { font-size: 11.5px; font-weight: 700; letter-spacing: 0.08em; color: var(--text-3); margin-bottom: 8px; } +.toc-nav { display: flex; flex-direction: column; gap: 1px; border-left: 2px solid var(--border); padding-left: 0; } +.toc-nav a { + font-size: 12.5px; color: var(--text-2); padding: 4px 0 4px 12px; text-decoration: none !important; + border-left: 2px solid transparent; margin-left: -2px; line-height: 1.5; +} +.toc-nav a:hover { color: var(--blue); } +.toc-nav a.toc-l3 { padding-left: 26px; font-size: 12px; color: var(--text-3); } +.toc-nav a.active { color: var(--blue); border-left-color: var(--blue); font-weight: 600; } +/* 404 */ +.doc-404 { display: grid; place-items: center; min-height: 100vh; text-align: center; } +.doc-404 h1 { font-size: 56px; margin: 0; color: var(--blue); } +.doc-404 .btn { + display: inline-block; margin-top: 12px; background: var(--blue); color: #fff; + padding: 8px 18px; border-radius: 8px; text-decoration: none !important; font-weight: 600; +} + +/* ---------- 响应式 ---------- */ +@media (max-width: 1200px) { + .layout { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); } + .toc { display: none; } +} +@media (max-width: 880px) { + .menu-btn { display: inline-grid; place-items: center; } + .layout { grid-template-columns: minmax(0, 1fr); padding-top: 12px; } + .sidebar { + position: fixed; z-index: 60; left: 0; top: var(--topbar-h); bottom: 0; + width: 280px; background: #fff; border-right: 1px solid var(--border); + padding: 16px; transform: translateX(-100%); transition: transform 0.2s; max-height: none; + } + .sidebar.open { transform: none; box-shadow: var(--shadow); } + .ver-badge { display: none; } + .top-links a { font-size: 12.5px; } + .page-title { font-size: 24px; } +} + +/* ---------- 打印 ---------- */ +@media print { + .topbar, .sidebar, .toc, .pn-nav, .feedback, .menu-btn { display: none !important; } + .layout { display: block; max-width: none; padding: 0; } + body { background: #fff; } + .md pre { background: #f1f5f9 !important; color: #1e293b !important; } + .md pre .copy-btn, .md pre .lang-tag { display: none; } +} + +/* ---------- LokiStack 品牌适配 ---------- */ +.brand-logo { + display: inline-flex; align-items: center; justify-content: center; + width: 28px; height: 28px; border-radius: 8px; + background: linear-gradient(135deg, #10b981, #047857); + color: #fff; font-weight: 800; font-size: 17px; +} + +/* 响应式(窄屏收起侧栏与目录) */ +@media (max-width: 1100px) { + .layout { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); } + .toc { display: none; } +} +@media (max-width: 860px) { + .layout { grid-template-columns: minmax(0, 1fr); padding: 16px 14px 40px; } + .menu-btn { display: grid; } + .sidebar { + position: fixed; z-index: 60; top: var(--topbar-h); left: 0; bottom: 0; + width: var(--sidebar-w); background: #fff; border-right: 1px solid var(--border); + transform: translateX(-100%); transition: transform 0.2s; max-height: none; padding: 14px 10px; + } + .sidebar.open { transform: none; box-shadow: var(--shadow); } + .search { max-width: none; } + .top-links { display: none; } +} + +.pn-empty { flex: 1; } diff --git a/homepage/dist/docs/assets/docs.js b/homepage/dist/docs/assets/docs.js new file mode 100644 index 0000000..833ffde --- /dev/null +++ b/homepage/dist/docs/assets/docs.js @@ -0,0 +1,196 @@ +/* LokiStack 文档站交互:搜索 / 代码复制 / 目录高亮 / 移动端导航(参考 opsxapi 体系) */ +(function () { + "use strict"; + + /* ---------- 代码块:语言标签 + 复制按钮 + 轻量高亮 ---------- */ + document.querySelectorAll("article.md pre").forEach(function (pre) { + var code = pre.querySelector("code"); + if (!code) return; + var lang = (code.className.match(/language-([\w-]+)/) || [, ""])[1]; + if (lang) { + var tag = document.createElement("span"); + tag.className = "lang-tag"; + tag.textContent = lang; + pre.appendChild(tag); + } + // 复制按钮 + var btn = document.createElement("button"); + btn.className = "copy-btn"; + btn.type = "button"; + btn.textContent = "复制"; + btn.addEventListener("click", function () { + navigator.clipboard.writeText(code.textContent).then( + function () { + btn.textContent = "已复制 ✓"; + setTimeout(function () { btn.textContent = "复制"; }, 1400); + }, + function () { btn.textContent = "复制失败"; } + ); + }); + pre.appendChild(btn); + // JSON / bash 轻量高亮 + if (lang === "json") highlightJSON(code); + else if (lang === "bash" || lang === "sh" || lang === "shell") highlightBash(code); + }); + + function esc(s) { + return s.replace(/&/g, "&").replace(//g, ">"); + } + function highlightJSON(code) { + var src = code.textContent; + code.innerHTML = esc(src).replace( + /("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g, + function (m, str, colon, kw, num) { + if (str && colon) return '' + str + "" + colon; + if (str) return '' + str + ""; + if (kw) return '' + kw + ""; + if (num) return '' + num + ""; + return m; + } + ); + } + function highlightBash(code) { + var lines = code.textContent.split("\n"); + code.innerHTML = lines + .map(function (line) { + if (/^\s*#/.test(line)) return '' + esc(line) + ""; + return esc(line).replace(/(^|\s)(-{1,2}[\w-]+)/g, '$1$2'); + }) + .join("\n"); + } + + /* ---------- blockquote 提示样式约定:> **提示** / > **注意** ---------- */ + document.querySelectorAll("article.md blockquote").forEach(function (bq) { + var t = (bq.textContent || "").trim(); + if (/^(注意|警告|⚠)/.test(t)) bq.classList.add("warn"); + else if (/^(提示|说明|💡|Tip)/i.test(t)) bq.classList.add("tip"); + }); + + /* ---------- 搜索 ---------- */ + var input = document.getElementById("search-input"); + var panel = document.getElementById("search-panel"); + var entries = null; + var selIndex = -1; + + function ensureIndex(cb) { + if (entries) return cb(); + fetch("/docs/search-data.json") + .then(function (r) { return r.json(); }) + .then(function (data) { entries = data; cb(); }) + .catch(function () { entries = []; cb(); }); + } + + function snippet(text, q) { + var i = text.toLowerCase().indexOf(q); + if (i < 0) return text.slice(0, 60) + "…"; + var start = Math.max(0, i - 24); + return (start > 0 ? "…" : "") + text.slice(start, i + q.length + 40) + "…"; + } + + function doSearch() { + var q = input.value.trim().toLowerCase(); + selIndex = -1; + if (!q) { panel.hidden = true; return; } + ensureIndex(function () { + var hits = []; + entries.forEach(function (e) { + var titleHit = e.title.toLowerCase().indexOf(q) >= 0; + var idx = e.text.toLowerCase().indexOf(q); + if (titleHit || idx >= 0) { + hits.push({ + slug: e.slug, + title: e.title, + group: e.group, + score: (titleHit ? 10 : 0) + (idx === 0 ? 3 : 0), + snippet: titleHit ? snippet(e.text, q) : snippet(e.text, q), + }); + } + }); + hits.sort(function (a, b) { return b.score - a.score; }); + hits = hits.slice(0, 8); + if (!hits.length) { + panel.innerHTML = '
没有找到相关内容,换个关键词试试
'; + } else { + panel.innerHTML = hits + .map(function (h) { + return ( + '' + + '' + h.title + '' + h.group + "" + + '' + h.snippet + "" + ); + }) + .join(""); + } + panel.hidden = false; + }); + } + + var debounce; + if (input) { + input.addEventListener("input", function () { + clearTimeout(debounce); + debounce = setTimeout(doSearch, 160); + }); + input.addEventListener("focus", function () { + if (input.value.trim()) doSearch(); + }); + input.addEventListener("keydown", function (e) { + var items = panel.querySelectorAll(".search-item"); + if (e.key === "ArrowDown" && items.length) { + e.preventDefault(); + selIndex = Math.min(selIndex + 1, items.length - 1); + } else if (e.key === "ArrowUp" && items.length) { + e.preventDefault(); + selIndex = Math.max(selIndex - 1, 0); + } else if (e.key === "Enter") { + if (selIndex >= 0 && items[selIndex]) { location.href = items[selIndex].href; return; } + var first = items[0]; + if (first) location.href = first.href; + return; + } else if (e.key === "Escape") { + panel.hidden = true; + return; + } else { + return; + } + items.forEach(function (el, i) { el.classList.toggle("sel", i === selIndex); }); + }); + document.addEventListener("click", function (e) { + if (!e.target.closest(".search")) panel.hidden = true; + }); + } + + /* ---------- 目录滚动高亮 ---------- */ + var tocLinks = Array.prototype.slice.call(document.querySelectorAll(".toc-nav a")); + if (tocLinks.length && "IntersectionObserver" in window) { + var byId = {}; + tocLinks.forEach(function (a) { byId[a.getAttribute("href").slice(1)] = a; }); + var io = new IntersectionObserver( + function (entries) { + entries.forEach(function (en) { + if (en.isIntersecting) { + tocLinks.forEach(function (a) { a.classList.remove("active"); }); + var a = byId[en.target.id]; + if (a) a.classList.add("active"); + } + }); + }, + { rootMargin: "-72px 0px -70% 0px", threshold: 0 } + ); + document.querySelectorAll("article.md h2[id], article.md h3[id]").forEach(function (h) { io.observe(h); }); + } + + + + /* ---------- 移动端侧栏 ---------- */ + var menuBtn = document.getElementById("menu-btn"); + var sidebar = document.getElementById("sidebar"); + if (menuBtn && sidebar) { + menuBtn.addEventListener("click", function () { sidebar.classList.toggle("open"); }); + document.addEventListener("click", function (e) { + if (sidebar.classList.contains("open") && !e.target.closest(".sidebar") && !e.target.closest(".menu-btn")) { + sidebar.classList.remove("open"); + } + }); + } +})(); diff --git a/homepage/dist/docs/assets/loki-docs.css b/homepage/dist/docs/assets/loki-docs.css new file mode 100644 index 0000000..13c3f73 --- /dev/null +++ b/homepage/dist/docs/assets/loki-docs.css @@ -0,0 +1,38 @@ + +:root{--brand:#059669;--brand-d: #047857;--ink:#0f172a;--muted:#5b6676;--line:#e6e9ee;--bg:#fff;--side:#f7f9f8} +*{box-sizing:border-box} +body{margin:0;font:15px/1.75 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;color:var(--ink);background:var(--bg)} +a{color:var(--brand-d);text-decoration:none}a:hover{text-decoration:underline} +.topbar{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:18px;height:56px;padding:0 20px;background:rgba(255,255,255,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--line)} +.brand{display:flex;align-items:center;gap:9px;font-weight:800;font-size:15px;color:var(--ink)} +.brand i{width:26px;height:26px;border-radius:8px;background:var(--brand);color:#fff;display:grid;place-items:center;font-style:normal;font-weight:800;font-size:14px} +.topnav{display:flex;gap:16px;margin-left:auto;font-size:14px} +.topnav a{color:var(--muted)}.topnav a:hover{color:var(--brand-d)} +.layout{display:grid;grid-template-columns:250px minmax(0,1fr) 200px;gap:34px;max-width:1240px;margin:0 auto;padding:26px 20px 70px} +aside.side{position:sticky;top:80px;align-self:start;max-height:calc(100vh - 100px);overflow:auto;font-size:14px} +.side h4{margin:18px 0 6px;font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:#93a0af;font-weight:700} +.side a{display:block;padding:5px 10px;border-radius:7px;color:#3b4656} +.side a:hover{background:var(--side);text-decoration:none} +.side a.on{background:#e8f7f1;color:var(--brand-d);font-weight:650} +article{min-width:0} +article h1{font-size:30px;line-height:1.3;margin:0 0 8px;letter-spacing:-.01em} +.meta{color:#98a2b3;font-size:12.5px;margin-bottom:22px} +article h2{font-size:21px;margin:32px 0 10px;padding-bottom:7px;border-bottom:1px solid var(--line)} +article h3{font-size:17px;margin:24px 0 8px} +article p{margin:12px 0} +article img{max-width:100%;height:auto;border:1px solid var(--line);border-radius:10px;margin:14px 0;box-shadow:0 1px 3px rgba(16,24,40,.06)} +article pre{background:#0f172a;color:#e6edf3;padding:14px 16px;border-radius:10px;overflow:auto;font-size:13px;line-height:1.6} +article code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px} +article :not(pre)>code{background:#f1f5f9;padding:2px 5px;border-radius:5px;color:#0f766e} +article table{border-collapse:collapse;width:100%;margin:14px 0;font-size:14px} +article th,article td{border:1px solid var(--line);padding:8px 10px;text-align:left} +article th{background:var(--side)} +article blockquote{margin:14px 0;padding:10px 16px;border-left:3px solid var(--brand);background:#f4fbf8;color:#33415c;border-radius:0 8px 8px 0} +.toc{position:sticky;top:84px;align-self:start;font-size:13px;color:var(--muted)} +.toc b{display:block;font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:#93a0af;margin-bottom:8px} +.toc a{display:block;padding:3px 0 3px 10px;border-left:2px solid var(--line);color:#5b6676} +.toc a:hover{color:var(--brand-d);border-color:var(--brand)} +.pager{display:flex;justify-content:space-between;gap:16px;margin-top:46px;padding-top:18px;border-top:1px solid var(--line);font-size:14px} +footer{border-top:1px solid var(--line);padding:20px;text-align:center;color:#98a2b3;font-size:12.5px} +@media (max-width:1080px){.layout{grid-template-columns:230px minmax(0,1fr)}.toc{display:none}} +@media (max-width:820px){.layout{grid-template-columns:1fr;padding-top:16px}aside.side{position:static;max-height:none;border-bottom:1px solid var(--line);padding-bottom:10px}.topnav{display:none}} diff --git a/homepage/dist/docs/assets/screenshots/alerts.png b/homepage/dist/docs/assets/screenshots/alerts.png new file mode 100644 index 0000000..1cd0861 Binary files /dev/null and b/homepage/dist/docs/assets/screenshots/alerts.png differ diff --git a/homepage/dist/docs/assets/screenshots/analysis.png b/homepage/dist/docs/assets/screenshots/analysis.png new file mode 100644 index 0000000..bf97022 Binary files /dev/null and b/homepage/dist/docs/assets/screenshots/analysis.png differ diff --git a/homepage/dist/docs/assets/screenshots/dashboard.png b/homepage/dist/docs/assets/screenshots/dashboard.png new file mode 100644 index 0000000..41824fc Binary files /dev/null and b/homepage/dist/docs/assets/screenshots/dashboard.png differ diff --git a/homepage/dist/docs/assets/screenshots/logs-query.png b/homepage/dist/docs/assets/screenshots/logs-query.png new file mode 100644 index 0000000..4a31a65 Binary files /dev/null and b/homepage/dist/docs/assets/screenshots/logs-query.png differ diff --git a/homepage/dist/docs/assets/screenshots/settings.png b/homepage/dist/docs/assets/screenshots/settings.png new file mode 100644 index 0000000..e400d08 Binary files /dev/null and b/homepage/dist/docs/assets/screenshots/settings.png differ diff --git a/homepage/dist/docs/assets/screenshots/wizard.png b/homepage/dist/docs/assets/screenshots/wizard.png new file mode 100644 index 0000000..9bee585 Binary files /dev/null and b/homepage/dist/docs/assets/screenshots/wizard.png differ diff --git a/homepage/dist/docs/assets/site.css b/homepage/dist/docs/assets/site.css new file mode 100644 index 0000000..ad537a5 --- /dev/null +++ b/homepage/dist/docs/assets/site.css @@ -0,0 +1,58 @@ +:root { + --brand: #059669; --brand-dark: #047857; --ink: #0f172a; --muted: #64748b; + --bg: #f8fafc; --card: #ffffff; --line: #e2e8f0; + --code-bg: #0f172a; --code-ink: #e2e8f0; +} +* { margin: 0; padding: 0; box-sizing: border-box; } +html { scroll-behavior: smooth; } +body { font-family: -apple-system, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif; color: var(--ink); background: var(--bg); line-height: 1.7; } +a { color: var(--brand); text-decoration: none; } +.container { max-width: 1080px; margin: 0 auto; padding: 0 24px; } + +.nav { position: sticky; top: 0; z-index: 10; background: rgba(255,255,255,.92); backdrop-filter: blur(8px); border-bottom: 1px solid var(--line); } +.nav-inner { max-width: 1080px; margin: 0 auto; padding: 14px 24px; display: flex; align-items: center; justify-content: space-between; } +.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 20px; color: var(--ink); } +.brand-logo { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 9px; background: linear-gradient(135deg, #10b981, #047857); color: #fff; font-weight: 800; } +.nav-links { display: flex; gap: 26px; font-size: 15px; } +.nav-links a { color: var(--muted); } +.nav-links a:hover { color: var(--ink); } + +.hero { padding: 96px 0 84px; text-align: center; background: radial-gradient(1200px 500px at 50% -100px, rgba(16,185,129,.12), transparent); } +.hero h1 { font-size: 46px; line-height: 1.25; letter-spacing: -1px; } +.hero h1 em { font-style: normal; color: var(--brand); } +.hero p.tagline { margin: 18px auto 0; max-width: 640px; font-size: 19px; color: var(--muted); } +.hero-actions { margin-top: 34px; display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; } +.btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 26px; border-radius: 10px; font-size: 16px; font-weight: 600; border: 1px solid transparent; transition: all .15s; } +.btn-primary { background: var(--brand); color: #fff; } +.btn-primary:hover { background: var(--brand-dark); } +.btn-outline { border-color: var(--line); color: var(--ink); background: var(--card); } +.btn-outline:hover { border-color: var(--brand); color: var(--brand); } +.hero-meta { margin-top: 26px; font-size: 14px; color: var(--muted); } + +section.block { padding: 72px 0; } +section.block.alt { background: var(--card); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); } +.block h2 { font-size: 30px; text-align: center; } +.block .sub { text-align: center; color: var(--muted); margin-top: 10px; margin-bottom: 44px; } + +.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; } +.feature { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 26px; } +.feature .icon { width: 42px; height: 42px; border-radius: 10px; display: flex; align-items: center; justify-content: center; background: rgba(16,185,129,.1); color: var(--brand); margin-bottom: 14px; } +.feature h3 { font-size: 17px; margin-bottom: 8px; } +.feature p { font-size: 14.5px; color: var(--muted); } + +.steps { max-width: 760px; margin: 0 auto; } +.step { display: flex; gap: 18px; padding: 18px 0; border-bottom: 1px dashed var(--line); } +.step:last-child { border-bottom: none; } +.step .no { flex-shrink: 0; width: 34px; height: 34px; border-radius: 50%; background: var(--brand); color: #fff; font-weight: 700; display: flex; align-items: center; justify-content: center; } +.step h3 { font-size: 16px; } +.step p { font-size: 14.5px; color: var(--muted); margin-top: 4px; } +code.inline { background: rgba(16,185,129,.08); color: var(--brand-dark); padding: 2px 7px; border-radius: 5px; font-size: 13.5px; font-family: ui-monospace, "SF Mono", Menlo, monospace; } + +.footer { padding: 40px 0 56px; color: var(--muted); font-size: 14px; text-align: center; } +.footer .links { display: flex; gap: 22px; justify-content: center; margin-bottom: 14px; } + +@media (max-width: 840px) { + .grid { grid-template-columns: 1fr; } + .hero h1 { font-size: 34px; } + .nav-links { display: none; } +} diff --git a/homepage/dist/docs/collectors/index.html b/homepage/dist/docs/collectors/index.html new file mode 100644 index 0000000..b14a0b1 --- /dev/null +++ b/homepage/dist/docs/collectors/index.html @@ -0,0 +1,39 @@ + + + +日志采集 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

日志采集

+
采集与查询 · 更新于 2026-10-28
+

「日志采集」页管理采集策略:主机采集(Promtail)与集群采集(DaemonSet / Fluent Bit Sidecar)。

+

采集范围

+ +

编辑与下发

+

保存后点击「部署」下发到目标;「预览 YAML」可先核对将生成的 promtail 配置。修改后同样以「部署」生效。

+

排查

+ + +
+ +
+ + diff --git a/homepage/dist/docs/faq/index.html b/homepage/dist/docs/faq/index.html new file mode 100644 index 0000000..8d96e5e --- /dev/null +++ b/homepage/dist/docs/faq/index.html @@ -0,0 +1,39 @@ + + + +常见问题 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

常见问题

+
告警与运维 · 更新于 2026-10-28
+

登录后看不到「部署向导」「用户管理」等菜单?

+

这些页面仅管理员可见。普通用户默认只有日志查询与日志告警;查询范围由策略组控制(见查询授权)。

+

部署的 Loki 怎么访问?必须配 Ingress 吗?

+

集群内部署经 API Server Service Proxy 查询,不需要 Ingress。跨集群 / 公网查询才需要为 Loki 暴露域名后在「数据源管理」用 URL 直连关联。

+

「停止部署」会删掉日志数据吗?

+

不会。停止只回收工作负载;数据卷(PVC / 主机数据目录)保留,重新启动即可恢复。仅显式删除部署记录不影响远端资源,卸载需按页面指引执行。

+

告警一直不发送?

+

按顺序检查:通道是否启用、Webhook 是否正确(通道页有测试)、规则是否启用且命中阈值、发送历史里是否有「冷却抑制」或失败原因。通道未就绪时历史会明确记录失败原因。

+

忘记管理员密码?

+

管理员可在「用户管理」重置任意账号密码;若唯一管理员丢失密码,参考仓库 README 的离线重置说明。

+

平台可以多实例部署吗?

+

不可以。JSON 文件存储为单实例设计(防抖串行落盘),水平扩展会互相覆盖;需要高可用时请保持单实例并对数据目录做系统级快照。

+

升级安全吗?

+

配置与数据向后兼容,结构变更按 schema 版本自动迁移;建议升级前对数据目录(lokistack.json)做一次文件级拷贝。

+ +
+ +
+ + diff --git a/homepage/dist/docs/index.html b/homepage/dist/docs/index.html new file mode 100644 index 0000000..eb9e08a --- /dev/null +++ b/homepage/dist/docs/index.html @@ -0,0 +1,46 @@ + + + +LokiStack 用户手册 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

LokiStack 用户手册

+
开始使用 · 更新于 2026-10-28
+

LokiStack 把 Grafana Loki 日志聚合的部署、采集、查询、分析与告警收进一个平台:向导式部署到 Kubernetes 集群或裸金属主机,内置中文/英文界面,单二进制交付。

+

平台能做什么

+ +

界面预览

+
+ 仪表盘 + 部署向导 + 日志查询 + 日志分析 + 告警通知 + 系统设置 +
+ +

下一步

+

阅读快速安装,或直接进入部署向导。

+ +
+ +
+ + diff --git a/homepage/dist/docs/install/index.html b/homepage/dist/docs/install/index.html new file mode 100644 index 0000000..26daa7d --- /dev/null +++ b/homepage/dist/docs/install/index.html @@ -0,0 +1,43 @@ + + + +快速安装 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

快速安装

+
开始使用 · 更新于 2026-10-28
+

方式一:Kubernetes

+
bash kubernetes/install.sh
+
+

方式二:Docker

+
docker compose up -d
+
+

方式三:单二进制

+
curl -LO https://gitea.91ai.io/rlwj-lab/LokiStack/releases/download/v2.0.0/lokistack-linux-amd64.tar.gz
+tar xzf lokistack-linux-amd64.tar.gz && cd lokistack-linux-amd64
+./lokistack
+
+

arm64 服务器下载 lokistack-linux-arm64.tar.gz。

+

说明

+ + +
+ +
+ + diff --git a/homepage/dist/docs/query/index.html b/homepage/dist/docs/query/index.html new file mode 100644 index 0000000..5de2c6c --- /dev/null +++ b/homepage/dist/docs/query/index.html @@ -0,0 +1,42 @@ + + + +日志查询 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

日志查询

+
采集与查询 · 更新于 2026-10-28
+

「日志查询」页(/logs)按 LogQL 与时间范围检索日志。

+

日志查询

+

查询方式

+ +

结果区

+ +

数据源

+

「数据源管理」维护 Loki 连接:平台部署自动注册(随部署托管),也可手动添加 URL 直连或集群 Service 数据源,支持 Basic / Bearer / 自定义 Header 认证与连接测试。

+ +
+ +
+ + diff --git a/homepage/dist/docs/readme/index.html b/homepage/dist/docs/readme/index.html new file mode 100644 index 0000000..eb9e08a --- /dev/null +++ b/homepage/dist/docs/readme/index.html @@ -0,0 +1,46 @@ + + + +LokiStack 用户手册 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

LokiStack 用户手册

+
开始使用 · 更新于 2026-10-28
+

LokiStack 把 Grafana Loki 日志聚合的部署、采集、查询、分析与告警收进一个平台:向导式部署到 Kubernetes 集群或裸金属主机,内置中文/英文界面,单二进制交付。

+

平台能做什么

+ +

界面预览

+
+ 仪表盘 + 部署向导 + 日志查询 + 日志分析 + 告警通知 + 系统设置 +
+ +

下一步

+

阅读快速安装,或直接进入部署向导。

+ +
+ +
+ + diff --git a/homepage/dist/docs/wizard/index.html b/homepage/dist/docs/wizard/index.html new file mode 100644 index 0000000..efadc02 --- /dev/null +++ b/homepage/dist/docs/wizard/index.html @@ -0,0 +1,67 @@ + + + +部署向导 · LokiStack 文档 + + + + + +
+ LLokiStack + 文档 + +
+
+ +
+

部署向导

+
开始使用 · 更新于 2026-10-28
+

部署向导(/wizard)三步完成 Loki 上线:环境与目标 → 存储 → 部署 Loki 与采集。

+

部署向导

+

第一步:环境与目标

+ +

创建后平台自动验证连通性;Kubernetes 资源默认落在 log 命名空间(可改)。

+

第二步:准备存储

+

推荐对象存储(MinIO / RustFS / S3 / OSS):多副本与数据保留更可靠,创建时可用「测试连接」验证凭证并自动建桶;跳过则使用本地磁盘。

+

第三步:部署与采集

+ +

三种部署模式

+ + + + + + + + + + + + + + + + + + + + + + + + + +
模式适用说明
k8s-yamlKubernetesStatefulSet + SSA 直发,平台全托管
host-binary裸金属SSH 安装二进制 + systemd 托管
host-docker裸金属Docker 容器运行,自动目录迁移
+ +
+ +
+ + diff --git a/homepage/dist/index.html b/homepage/dist/index.html new file mode 100644 index 0000000..b62057a --- /dev/null +++ b/homepage/dist/index.html @@ -0,0 +1,132 @@ + + + + + +LokiStack — Loki 日志管理平台 + + + + + + + + + + +
+
+

把 Loki 日志聚合
变成五分钟的事

+

向导式部署 Grafana Loki 到 Kubernetes 集群或裸金属主机,内置日志查询、可视化分析与飞书告警 —— 不写 YAML、不装 kubectl/Helm。

+ +

Go + React 单二进制交付 · JSON 文件存储零依赖 · 中文/英文界面

+
+
+ +
+
+

为运维而生的完整日志链路

+

从部署、采集、查询到告警,一个平台全部覆盖

+
+
+
+

向导式部署

+

三步完成:环境与目标 → 存储 → 部署 Loki 与采集。支持 Kubernetes(YAML 直发)、裸金属二进制与 Docker 三种模式。

+
+
+
+

策略化采集

+

Promtail / Fluent Bit 采集策略可视化配置:命名空间多选、app 标签四级回退、敏感路径拦截、配置预览与一键下发。

+
+
+
+

专业日志查询

+

LogQL 高亮补全、快捷查询选中即执行、Live Tail 实时追踪、时间线拖选、上下文查看,细到按用户的查询授权。

+
+
+
+

日志分析大盘

+

统计卡、趋势折线、命名空间分布、应用流图、每日日志量、Top 10 排行与 Ingress 访问分析,自动聚合无需配置。

+
+
+
+

开箱告警

+

内置九条应用日志告警规则,默认启用并绑定默认通道;填好飞书 Webhook 即可接收,冷却与风暴抑制防刷屏。

+
+
+
+

工程级可靠性

+

凭证加密存储、操作审计、标准 Prometheus 指标端点、CI 门禁与测试覆盖,按生产标准构建。

+
+
+
+
+ +
+
+

五分钟启动

+

单二进制或 Docker,一条命令拉起完整平台

+
+
+ 1 +
+

准备密钥并启动

+

export JWT_SECRET=... ENCRYPTION_KEY=... 后执行 ./run.sh(开发)或 docker compose up -d(生产)。默认账号在首次启动时自动生成。

+
+
+
+ 2 +
+

走完部署向导

+

接入 Kubernetes 集群或 SSH 主机,选择对象存储或本地磁盘,三步部署 Loki 并下发采集策略。

+
+
+
+ 3 +
+

查询、分析、告警

+

日志查询页检索与实时追踪,日志分析页看聚合大盘,告警页填入飞书 Webhook 开始接收告警。

+
+
+
+
+
+ +
+
+

文档

+

用户手册覆盖部署、采集、查询、分析与告警全流程

+ +
+
+ + + + + diff --git a/homepage/dist/pricing.html b/homepage/dist/pricing.html new file mode 100644 index 0000000..bb55dbf --- /dev/null +++ b/homepage/dist/pricing.html @@ -0,0 +1,213 @@ + + + + + +License & Pricing 许可和定价 · LokiStack + + + + + + + + +
+ LLokiStack + + +
+ + + +
+
+ 30 天全功能试用 · 离线可激活 · 无需注册 +

License & Pricing
许可和定价

+

社区版永久免费;专业版 ¥99/年起,永久授权 ¥199 一次买断。所有版本功能完整,差别只在授权方式与设备数。

+
+ +
+
+
+

社区版

个人 / 非商业使用
+
¥0/ 永久
+
    +
  • 日志采集与查询
  • 告警规则与通知
  • 基础仪表盘
  • 单机部署
  • 社区支持
  • +
+ 免费开始 +
+
+ 最受欢迎 +

专业版 · 包年

单设备授权 · 全功能
+
¥99/ 年
+
    +
  • 全部功能 + 高级分析
  • 在线授权 LIC-
  • 1 台设备
  • 一年免费升级
  • 邮件技术支持
  • +
+ 立即购买 +
+
+

专业版 · 永久

一次买断 · 离线许可
+
¥199/ 永久
+
    +
  • 当前大版本永久可用
  • 离线许可 LICOFF-
  • 1 台设备
  • 1 年免费升级
  • 邮件技术支持
  • +
+ 立即购买 +
+
+

企业私有化

按席位 · 5 席起
+
¥6,000起 / 年
+
    +
  • 集群 / 高可用部署
  • 私有化与白牌交付
  • SSO / 审计 / 数据留存
  • 专属支持与培训
  • 可签合同与发票
  • +
+ 预约报价 +
+
+
+ +
+

激活:粘贴授权码即可

+

付款后我们通过邮件交付授权码。在线授权以 LIC- 开头,离线许可证文件以 LICOFF- 开头。

+
+
邮件收码付款后 1 个工作日内,授权码发送到你预留的邮箱
+
打开设置程序内「设置 → 账户 / 授权」
+
粘贴激活填入 LIC-… 点击激活;离线环境导入 LICOFF- 文件
+
完成状态显示「已激活 / 剩余 N 天」,可在同一页解绑换机
+
+
+ +
+

常见问题

+
授权如何交付?包含哪些内容?

邮件交付授权码 + 发票。授权与设备绑定,包含对应版本的全部功能与一年升级。

+
换电脑怎么办?

在程序「设置 → 授权」里先解绑,再在新设备激活;解绑次数不限,同一时间仅一台设备在线。

+
可以离线使用吗?

可以。选择永久/离线许可,我们会提供 LICOFF- 许可证文件,导入后无需联网校验。

+
团队 / 企业怎么买?

5 席起按席位计价,支持私有化与白牌交付、SSO 与审计。邮件说明规模与环境,我们给方案与报价。

+
怎么付款?支持哪些方式?

对公转账 / 支付宝,支持开票。本站不介入在线支付,付款与发票均走人工邮件确认。

+
+ +
+

先用起来,再决定

下载即含 30 天全功能试用,到期前随时激活。

+ 打开用户手册 +
+
+ + + + + + diff --git a/homepage/index.html b/homepage/index.html index 00970ce..b62057a 100644 --- a/homepage/index.html +++ b/homepage/index.html @@ -7,6 +7,8 @@ + + @@ -18,9 +20,8 @@ @@ -30,8 +31,8 @@

把 Loki 日志聚合
变成五分钟的事

向导式部署 Grafana Loki 到 Kubernetes 集群或裸金属主机,内置日志查询、可视化分析与飞书告警 —— 不写 YAML、不装 kubectl/Helm。

- 快速开始 - 阅读文档 + 快速开始 + 阅读文档

Go + React 单二进制交付 · JSON 文件存储零依赖 · 中文/英文界面

@@ -112,7 +113,7 @@

用户手册覆盖部署、采集、查询、分析与告警全流程

打开用户手册 - 查看源码 + 许可和定价
@@ -120,7 +121,7 @@