Initial commit

This commit is contained in:
2026-04-21 13:49:12 +08:00
commit 272d0973bd
6 changed files with 1495 additions and 0 deletions

935
index.html Normal file
View File

@@ -0,0 +1,935 @@
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>dotlog — 把所有日誌管線串成一行</title>
<meta name="description" content="dotlog 是為工程師而生的 CLI 工具:一條指令完成擷取、過濾、聚合、輸出。" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
<style>
/* ===================== Tokens ===================== */
:root {
--background: #fcfcfc;
--foreground: #171717;
--card: #fcfcfc;
--primary: #00bb7f;
--primary-soft: rgba(0, 187, 127, 0.25);
--primary-bg: rgba(0, 187, 127, 0.10);
--secondary: #fdfdfd;
--muted: #ededed;
--muted-foreground: #525252;
--neutral-400: #a1a1a1;
--accent: #ededed;
--border: #dfdfdf;
--ring: #72e3ad;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
--shadow-lg: 0 12px 32px -14px rgba(0, 0, 0, 0.18);
--radius-xs: 4px;
--radius-md: 10px;
--radius-2xl: 16px;
--radius-3xl: 24px;
--font-sans: "Space Grotesk", system-ui, -apple-system, "Noto Sans TC", sans-serif;
--font-mono: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
--transition: 150ms cubic-bezier(0.4, 0, 0.2, 1);
--container: 1152px;
}
html.dark {
--background: #121212;
--foreground: #e2e8f0;
--card: #171717;
--primary: #00bb7f;
--primary-soft: rgba(74, 222, 128, 0.30);
--primary-bg: rgba(0, 187, 127, 0.14);
--secondary: #242424;
--muted: #1f1f1f;
--muted-foreground: #a2a2a2;
--accent: #313131;
--border: #292929;
--ring: #4ade80;
--shadow-lg: 0 12px 32px -14px rgba(0, 0, 0, 0.6);
}
/* ===================== Reset ===================== */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--font-sans);
background: var(--background);
color: var(--foreground);
font-size: 16px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
transition: background var(--transition), color var(--transition);
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; padding: 0; }
code { font-family: var(--font-mono); background: var(--muted); padding: 1px 6px; border-radius: var(--radius-xs); font-size: 0.875em; }
.container {
max-width: var(--container);
margin: 0 auto;
padding: 0 24px;
}
/* ===================== Header ===================== */
.site-header {
position: sticky;
top: 0;
z-index: 50;
height: 64px;
display: flex;
align-items: center;
background: color-mix(in srgb, var(--background) 78%, transparent);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-bottom: 1px solid var(--border);
}
.site-header .container {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.brand {
display: flex;
align-items: center;
gap: 10px;
font-weight: 700;
font-size: 18px;
letter-spacing: -0.01em;
}
.brand-dot {
width: 10px; height: 10px;
border-radius: 50%;
background: var(--primary);
box-shadow: 0 0 10px var(--primary);
}
.nav {
display: flex;
align-items: center;
gap: 6px;
}
.nav > a {
padding: 8px 12px;
font-size: 14px;
color: var(--muted-foreground);
border-radius: 8px;
transition: color var(--transition);
}
.nav > a:hover { color: var(--primary); }
.theme-toggle {
width: 36px; height: 36px;
border-radius: var(--radius-md);
display: grid;
place-items: center;
border: 1px solid var(--border);
transition: background var(--transition), border-color var(--transition);
margin: 0 4px;
}
.theme-toggle:hover { background: var(--accent); border-color: var(--primary-soft); }
.theme-toggle svg { width: 16px; height: 16px; }
.theme-toggle .sun { display: none; }
html.dark .theme-toggle .sun { display: block; }
html.dark .theme-toggle .moon { display: none; }
.nav-github {
padding: 8px 14px !important;
font-size: 13.5px !important;
border-radius: 12px !important;
}
@media (max-width: 639px) {
.nav > a:not(.nav-github) { display: none; }
}
/* ===================== Buttons ===================== */
.btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
border-radius: var(--radius-2xl);
font-weight: 600;
font-size: 15px;
transition: transform var(--transition), box-shadow var(--transition), background var(--transition), border-color var(--transition), color var(--transition);
border: 1px solid transparent;
cursor: pointer;
white-space: nowrap;
}
.btn-primary {
background: var(--primary);
color: #fff;
}
.btn-primary:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-lg);
}
.btn-outline {
background: transparent;
color: var(--foreground);
border-color: var(--border);
}
.btn-outline:hover {
background: var(--accent);
border-color: var(--primary);
}
/* ===================== Hero ===================== */
.hero {
padding: 96px 0 72px;
text-align: center;
position: relative;
overflow: hidden;
}
.hero::before {
content: "";
position: absolute;
inset: 0;
background:
radial-gradient(ellipse 60% 50% at 50% 0%, var(--primary-bg), transparent 70%);
pointer-events: none;
}
.hero > * { position: relative; }
.hero h1 {
font-size: clamp(36px, 7.2vw, 72px);
line-height: 1.02;
letter-spacing: -0.03em;
font-weight: 700;
margin: 0 0 24px;
}
.hero h1 .accent { color: var(--primary); }
.hero .subtitle {
font-size: clamp(16px, 1.5vw, 20px);
line-height: 1.55;
color: var(--muted-foreground);
max-width: 42rem;
margin: 0 auto 28px;
}
.hero-badges {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 12px 14px;
margin-bottom: 40px;
font-size: 13px;
color: var(--muted-foreground);
font-family: var(--font-mono);
}
.hero-badges .sep { color: var(--neutral-400); }
.hero-ctas {
display: flex;
justify-content: center;
gap: 12px;
flex-wrap: wrap;
}
/* ===================== Section base ===================== */
.section {
padding: 80px 0;
border-top: 1px solid var(--border);
}
.section-head {
text-align: center;
margin-bottom: 56px;
}
.section-kicker {
font-family: var(--font-mono);
font-size: 12.5px;
color: var(--primary);
letter-spacing: 0.12em;
text-transform: uppercase;
margin-bottom: 14px;
font-weight: 500;
}
.section h2 {
font-size: clamp(30px, 4.2vw, 48px);
line-height: 1.1;
font-weight: 700;
margin: 0 0 14px;
letter-spacing: -0.02em;
}
.section-sub {
color: var(--muted-foreground);
font-size: 16.5px;
max-width: 40rem;
margin: 0 auto;
line-height: 1.6;
}
/* ===================== Grids ===================== */
.grid-4 {
display: grid;
gap: 20px;
grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1023px) { .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 559px) { .grid-4 { grid-template-columns: 1fr; } }
.grid-steps {
display: grid;
gap: 20px;
grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1023px) { .grid-steps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 559px) { .grid-steps { grid-template-columns: 1fr; } }
.grid-apps {
display: grid;
gap: 20px;
grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 767px) { .grid-apps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 479px) { .grid-apps { grid-template-columns: 1fr; } }
/* ===================== Card ===================== */
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius-2xl);
padding: 24px;
transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
}
.card:hover {
border-color: var(--primary-soft);
box-shadow: var(--shadow-lg);
transform: translateY(-2px);
}
.card .icon {
width: 40px; height: 40px;
display: grid; place-items: center;
border-radius: var(--radius-md);
background: var(--primary-bg);
color: var(--primary);
margin-bottom: 18px;
}
.card .icon svg { width: 20px; height: 20px; stroke-width: 1.6; }
.card h3 {
font-size: 17px;
margin: 0 0 8px;
font-weight: 600;
letter-spacing: -0.01em;
}
.card p {
margin: 0;
color: var(--muted-foreground);
font-size: 14.5px;
line-height: 1.55;
}
/* ===================== Step ===================== */
.step .num {
font-family: var(--font-mono);
font-size: 44px;
font-weight: 600;
color: var(--primary);
line-height: 1;
margin-bottom: 16px;
}
.step h3 {
font-size: 16px;
font-weight: 600;
margin: 0 0 14px;
}
.cmd {
font-family: var(--font-mono);
font-size: 13px;
background: var(--muted);
color: var(--foreground);
padding: 8px 12px;
border-radius: var(--radius-xs);
display: block;
white-space: nowrap;
overflow-x: auto;
max-width: 100%;
}
.cmd::-webkit-scrollbar { height: 0; }
/* ===================== App card ===================== */
.app-card h3 {
font-size: 15.5px;
font-weight: 600;
margin: 0 0 14px;
}
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.tag {
font-family: var(--font-mono);
font-size: 11.5px;
background: var(--muted);
color: var(--muted-foreground);
padding: 3px 8px;
border-radius: var(--radius-xs);
}
/* ===================== Pipeline ===================== */
.pipeline-wrap {
max-width: 960px;
margin: 0 auto;
}
.pipeline {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
position: relative;
padding: 40px 0 32px;
}
.pipeline::before {
content: "";
position: absolute;
top: 47px;
left: 7%;
right: 7%;
height: 2px;
background: linear-gradient(to right,
var(--primary-soft),
var(--primary) 15%,
var(--primary) 85%,
var(--primary-soft));
z-index: 0;
opacity: 0.55;
}
.stage {
flex: 1;
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.stage .dot {
width: 14px; height: 14px;
border-radius: 50%;
background: var(--primary);
margin: 0 0 18px;
box-shadow:
0 0 0 4px var(--background),
0 0 0 6px var(--primary-soft);
}
.stage .num-sm {
font-family: var(--font-mono);
font-size: 11px;
color: var(--muted-foreground);
margin-bottom: 2px;
letter-spacing: 0.05em;
}
.stage .label {
font-size: 14px;
color: var(--foreground);
font-weight: 500;
}
@media (max-width: 767px) {
.pipeline {
flex-direction: column;
gap: 8px;
padding-left: 20px;
}
.pipeline::before {
top: 40px;
bottom: 40px;
left: 26px;
right: auto;
width: 2px;
height: auto;
background: linear-gradient(to bottom,
var(--primary-soft),
var(--primary) 15%,
var(--primary) 85%,
var(--primary-soft));
}
.stage {
flex-direction: row;
align-items: center;
gap: 14px;
text-align: left;
flex: none;
padding: 8px 0;
}
.stage .dot { margin: 0; flex-shrink: 0; }
.stage-meta { display: flex; flex-direction: column; }
}
/* ===================== FAQ ===================== */
.faq {
max-width: 760px;
margin: 0 auto;
}
.faq details {
border-bottom: 1px solid var(--border);
padding: 20px 4px;
}
.faq details:first-child { border-top: 1px solid var(--border); }
.faq details[open] summary { color: var(--primary); }
.faq summary {
list-style: none;
cursor: pointer;
font-weight: 600;
font-size: 16px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
transition: color var(--transition);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
content: "+";
font-family: var(--font-mono);
font-size: 22px;
color: var(--primary);
line-height: 1;
transition: transform var(--transition);
flex-shrink: 0;
}
.faq details[open] summary::after {
content: "";
}
.faq .answer {
color: var(--muted-foreground);
margin-top: 14px;
font-size: 15px;
line-height: 1.65;
}
/* ===================== Footer ===================== */
.site-footer {
border-top: 1px solid var(--border);
padding: 56px 0 32px;
}
.footer-grid {
display: grid;
gap: 32px;
grid-template-columns: 1.5fr 1fr 1fr 1fr;
}
@media (max-width: 767px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 479px) { .footer-grid { grid-template-columns: 1fr; } }
.footer-brand p {
color: var(--muted-foreground);
font-size: 14px;
margin: 14px 0 0;
line-height: 1.65;
max-width: 22rem;
}
.footer-col h4 {
font-size: 12px;
font-weight: 600;
margin: 0 0 16px;
color: var(--foreground);
text-transform: uppercase;
letter-spacing: 0.1em;
font-family: var(--font-mono);
}
.footer-col ul {
list-style: none;
padding: 0; margin: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.footer-col a {
color: var(--muted-foreground);
font-size: 14px;
transition: color var(--transition);
}
.footer-col a:hover { color: var(--primary); }
.copyright {
text-align: center;
margin-top: 48px;
padding-top: 24px;
border-top: 1px solid var(--border);
font-size: 13px;
color: var(--neutral-400);
font-family: var(--font-mono);
}
/* ===================== Focus ring ===================== */
:is(a, button, summary, .btn):focus-visible {
outline: 2px solid var(--ring);
outline-offset: 3px;
border-radius: 10px;
}
/* ===================== Fade-up ===================== */
.fade-up {
opacity: 0;
transform: translateY(14px);
transition:
opacity 520ms cubic-bezier(0.4, 0, 0.2, 1),
transform 520ms cubic-bezier(0.4, 0, 0.2, 1);
}
.fade-up.visible {
opacity: 1;
transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
.fade-up { opacity: 1; transform: none; transition: none; }
html { scroll-behavior: auto; }
}
/* ===================== Mobile tweaks ===================== */
@media (max-width: 639px) {
.hero { padding: 56px 0 48px; }
.section { padding: 64px 0; }
.section-head { margin-bottom: 40px; }
}
</style>
</head>
<body>
<!-- ============ Header ============ -->
<header class="site-header">
<div class="container">
<a href="#top" class="brand" aria-label="dotlog 首頁">
<span class="brand-dot" aria-hidden="true"></span>
<span>dotlog</span>
</a>
<nav class="nav" aria-label="主要導覽">
<a href="#features">功能特性</a>
<a href="#steps">文件</a>
<a href="#faq">FAQ</a>
<button class="theme-toggle" type="button" id="themeToggle" aria-label="切換深淺主題">
<svg class="moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
<svg class="sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="4"/>
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
</svg>
</button>
<a href="#" class="btn btn-primary nav-github">在 GitHub 查看</a>
</nav>
</div>
</header>
<main id="top">
<!-- ============ Hero ============ -->
<section class="hero">
<div class="container">
<h1 class="fade-up">
把所有日誌管線<br/>
<span class="accent">串成一行</span>
</h1>
<p class="subtitle fade-up">
dotlog 是為工程師而生的 CLI 工具。一條指令完成擷取、過濾、聚合、輸出,取代雜亂的 shell pipeline 與多套 daemon。
</p>
<div class="hero-badges fade-up">
<span>⭐ 1.2k Stars</span>
<span class="sep">·</span>
<span>98% 測試通過</span>
<span class="sep">·</span>
<span>MIT 授權</span>
</div>
<div class="hero-ctas fade-up">
<a href="#steps" class="btn btn-primary">立即開始</a>
<a href="#" class="btn btn-outline">在 GitHub 查看</a>
</div>
</div>
</section>
<!-- ============ Why dotlog ============ -->
<section class="section" id="features">
<div class="container">
<div class="section-head fade-up">
<div class="section-kicker">Why dotlog</div>
<h2>為什麼選擇 dotlog</h2>
<p class="section-sub">不需要 YAML、不需要 daemon、不需要額外的容器。一支二進位檔裝了就能用。</p>
</div>
<div class="grid-4">
<article class="card fade-up">
<div class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
</div>
<h3>零配置啟動</h3>
<p>裝了就跑,不需要設定檔。<code>dotlog tap nginx</code> 一行搞定。</p>
</article>
<article class="card fade-up">
<div class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 10h18"/><path d="M8 14h2M8 17h5"/></svg>
</div>
<h3>全格式支援</h3>
<p>JSON、syslog、Apache、Nginx、K8s events 自動偵測並結構化。</p>
</article>
<article class="card fade-up">
<div class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h4l3-9 4 18 3-9h4"/></svg>
</div>
<h3>低資源佔用</h3>
<p>Rust 撰寫,單一二進位檔 6MB常駐記憶體不到 15MB。</p>
</article>
<article class="card fade-up">
<div class="icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/><polyline points="7 11 12 16 17 11"/><line x1="12" y1="4" x2="12" y2="16"/></svg>
</div>
<h3>原生輸出整合</h3>
<p>直接送進 S3、Loki、OpenTelemetry、Kafka無須轉接器。</p>
</article>
</div>
</div>
</section>
<!-- ============ Quick Start ============ -->
<section class="section" id="steps">
<div class="container">
<div class="section-head fade-up">
<div class="section-kicker">Quick Start</div>
<h2>5 分鐘上手</h2>
<p class="section-sub">四個指令,把你的伺服器日誌送到雲端。</p>
</div>
<div class="grid-steps">
<article class="step card fade-up">
<div class="num">01</div>
<h3>安裝</h3>
<code class="cmd">brew install dotlog</code>
</article>
<article class="step card fade-up">
<div class="num">02</div>
<h3>初始化</h3>
<code class="cmd">dotlog init</code>
</article>
<article class="step card fade-up">
<div class="num">03</div>
<h3>指定來源</h3>
<code class="cmd">dotlog tap nginx</code>
</article>
<article class="step card fade-up">
<div class="num">04</div>
<h3>串接輸出</h3>
<code class="cmd">dotlog pipe → s3</code>
</article>
</div>
</div>
</section>
<!-- ============ Integrations ============ -->
<section class="section">
<div class="container">
<div class="section-head fade-up">
<div class="section-kicker">Integrations</div>
<h2>你正在用的工具,它都支援</h2>
<p class="section-sub">開箱即用 60+ 種資料來源與 20+ 種輸出目標。</p>
</div>
<div class="grid-apps">
<article class="card app-card fade-up">
<h3>Web 伺服器</h3>
<div class="tag-list">
<span class="tag">nginx</span><span class="tag">apache</span><span class="tag">caddy</span><span class="tag">traefik</span>
</div>
</article>
<article class="card app-card fade-up">
<h3>容器</h3>
<div class="tag-list">
<span class="tag">docker</span><span class="tag">kubernetes</span><span class="tag">containerd</span><span class="tag">podman</span>
</div>
</article>
<article class="card app-card fade-up">
<h3>資料庫</h3>
<div class="tag-list">
<span class="tag">postgres</span><span class="tag">mysql</span><span class="tag">redis</span><span class="tag">mongo</span>
</div>
</article>
<article class="card app-card fade-up">
<h3>雲端服務</h3>
<div class="tag-list">
<span class="tag">aws-s3</span><span class="tag">gcs</span><span class="tag">cloudwatch</span><span class="tag">azure-logs</span>
</div>
</article>
<article class="card app-card fade-up">
<h3>訊息佇列</h3>
<div class="tag-list">
<span class="tag">kafka</span><span class="tag">nats</span><span class="tag">rabbitmq</span><span class="tag">sqs</span>
</div>
</article>
<article class="card app-card fade-up">
<h3>監控</h3>
<div class="tag-list">
<span class="tag">loki</span><span class="tag">datadog</span><span class="tag">otel</span><span class="tag">prometheus</span>
</div>
</article>
</div>
</div>
</section>
<!-- ============ Pipeline ============ -->
<section class="section">
<div class="container">
<div class="section-head fade-up">
<div class="section-kicker">Core Pipeline</div>
<h2>七個階段的完整流水線</h2>
<p class="section-sub">每一階段都能被單獨替換、停用或擴充。</p>
</div>
<div class="pipeline-wrap fade-up">
<div class="pipeline" role="list">
<div class="stage" role="listitem">
<div class="dot" aria-hidden="true"></div>
<div class="stage-meta">
<span class="num-sm">01</span>
<span class="label">擷取</span>
</div>
</div>
<div class="stage" role="listitem">
<div class="dot" aria-hidden="true"></div>
<div class="stage-meta">
<span class="num-sm">02</span>
<span class="label">解析</span>
</div>
</div>
<div class="stage" role="listitem">
<div class="dot" aria-hidden="true"></div>
<div class="stage-meta">
<span class="num-sm">03</span>
<span class="label">正規化</span>
</div>
</div>
<div class="stage" role="listitem">
<div class="dot" aria-hidden="true"></div>
<div class="stage-meta">
<span class="num-sm">04</span>
<span class="label">路由</span>
</div>
</div>
<div class="stage" role="listitem">
<div class="dot" aria-hidden="true"></div>
<div class="stage-meta">
<span class="num-sm">05</span>
<span class="label">過濾</span>
</div>
</div>
<div class="stage" role="listitem">
<div class="dot" aria-hidden="true"></div>
<div class="stage-meta">
<span class="num-sm">06</span>
<span class="label">聚合</span>
</div>
</div>
<div class="stage" role="listitem">
<div class="dot" aria-hidden="true"></div>
<div class="stage-meta">
<span class="num-sm">07</span>
<span class="label">輸出</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============ FAQ ============ -->
<section class="section" id="faq">
<div class="container">
<div class="section-head fade-up">
<div class="section-kicker">FAQ</div>
<h2>常見問題</h2>
</div>
<div class="faq fade-up">
<details>
<summary>dotlog 的授權是什麼?</summary>
<div class="answer">採用 MIT 授權,商用、修改、再散布都沒有限制,無需付費。</div>
</details>
<details>
<summary>效能表現如何?</summary>
<div class="answer">在單一 vCPU 上可處理約 120k events/秒,約為 Fluentd 的 4 倍,記憶體佔用不到 1/5。</div>
</details>
<details>
<summary>與 Fluentd / Vector / Filebeat 有什麼差異?</summary>
<div class="answer">dotlog 強調 <strong>CLI 優先與零配置</strong>:用熟悉的 shell 就能組裝管線,無需學習自訂 DSL也不需要部署守護程序。適合需要快速串接或臨時任務的場景。</div>
</details>
<details>
<summary>支援哪些部署方式?</summary>
<div class="answer">單一靜態二進位檔,直接在 macOS、Linux、Windows 執行;也提供官方 Docker image 與 Helm chart。</div>
</details>
<details>
<summary>資料會經過你們的伺服器嗎?</summary>
<div class="answer">完全不會。dotlog 是純本地執行的工具,所有日誌只在你指定的來源與輸出之間傳遞,專案本身不收集任何遙測資料(可用 <code>--telemetry=off</code> 再次關閉驗證)。</div>
</details>
</div>
</div>
</section>
</main>
<!-- ============ Footer ============ -->
<footer class="site-footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="brand">
<span class="brand-dot" aria-hidden="true"></span>
<span>dotlog</span>
</div>
<p>把所有日誌管線串成一行。為工程師而生的開源 CLI 工具。</p>
</div>
<div class="footer-col">
<h4>產品</h4>
<ul>
<li><a href="#features">功能特性</a></li>
<li><a href="#steps">快速上手</a></li>
<li><a href="#">更新日誌</a></li>
</ul>
</div>
<div class="footer-col">
<h4>資源</h4>
<ul>
<li><a href="#">文件</a></li>
<li><a href="#">GitHub</a></li>
<li><a href="#">社群討論</a></li>
</ul>
</div>
<div class="footer-col">
<h4>法律</h4>
<ul>
<li><a href="#">授權條款</a></li>
<li><a href="#">隱私政策</a></li>
</ul>
</div>
</div>
<div class="copyright">© 2026 dotlog · MIT License</div>
</div>
</footer>
<script>
// ==== Theme toggle ====
(function () {
const root = document.documentElement;
const toggle = document.getElementById('themeToggle');
const stored = localStorage.getItem('dotlog-theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (stored === 'dark' || (!stored && prefersDark)) {
root.classList.add('dark');
}
toggle.addEventListener('click', () => {
root.classList.toggle('dark');
localStorage.setItem('dotlog-theme', root.classList.contains('dark') ? 'dark' : 'light');
});
})();
// ==== Fade-up on scroll ====
(function () {
const items = document.querySelectorAll('.fade-up');
if (!('IntersectionObserver' in window)) {
items.forEach((el) => el.classList.add('visible'));
return;
}
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting) {
e.target.classList.add('visible');
io.unobserve(e.target);
}
});
}, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });
items.forEach((el) => io.observe(el));
})();
</script>
</body>
</html>