---
title: "From Installation to Implementation! A Practical Guide to Grafana + Loki for Next.js Logging"
description: "From deploying Loki and Grafana with Docker to integrating winston-loki in a Next.js backend, a complete guide on how to build a centralized log collection and visual monitoring system."
canonical_url: "https://blog.markkulab.net/en/post/from-installation-to-implementation-grafana-loki-nextjs-logging-guide"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/en/author/mark-ku"
site: "Mark Ku's Tech Notes"
date_published: "2024-11-07 20:01:35 +0800"
category: "DevOps"
tags: ["grafana", "loki", "nextjs", "logging", "monitoring", "docker", "devops", "winston"]
language: "en"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "when reusing or quoting, credit the author and link back to the original"
---

# From Installation to Implementation! A Practical Guide to Grafana + Loki for Next.js Logging

## Introduction
We manage websites for multiple countries and were originally using Seq as our log server. However, since only one person could be logged in at a time and each country required its own container service, we decided to switch to Grafana to simplify operations and maintenance. While learning K8s, I discovered that Grafana, Loki, and Prometheus are a common, standard setup.

## First, What is Grafana?
Grafana is an open-source data visualization and monitoring platform that allows you to easily create interactive dashboards to monitor system status in real-time from various data sources. It's primarily composed of the following three services.

*   **Grafana**: This is the visualization platform. It can integrate data from various sources (like Loki and Prometheus) and create charts and dashboards for easy monitoring.
*   **Loki**: This is specifically for collecting and managing log data. When integrated with Grafana, you can analyze logs and monitoring data on the same platform to quickly identify issues.
*   **Prometheus**: Its main responsibility is to collect and store system monitoring metrics, providing a basis for monitoring system health.

## Open-Source Logging Services
Based on feedback from several developers online, for a pure logging service, Graylog is a good option for on-premise deployments and is also a great piece of logging software. However, Loki's advantage is that it's lightweight, which can save resources when deploying to the cloud. Loki is also easier to integrate with other products in the Grafana stack.

## Next, Deploying the Loki Logging System
```
docker run -d --name=loki -p 3100:3100 grafana/loki:latest
```
## Loki supports a RESTful API, so we can interact with it using Curl.
### Add a Log Entry
```
# const createdAt = Date.now() * 1_000_000; // js 將計算後的結果貼到這裡 createdAt
@createdAt = 1693022700000000  


POST http://localhost:3100/loki/api/v1/push
Content-Type: application/json

{
    "streams": [
        {
            "stream": {
              "app":"nextjs-app" // 可以將你的動態資料放在這，可用來分類、篩選、繪製報表
            },
            "values": [
                ["{{createdAt}}", "write your logs in here"]
            ]
        }
    ]
}
```
### Query Logs
 
```
GET http://localhost:3100/loki/api/v1/query?query={app="nextjs-app"}&limit=10
```

## Next, Let's Install Grafana
### Run the Grafana Container Service
```
docker run -d --name=grafana -p 7777:3000 grafana/grafana
```
### [Log in to the dashboard](http://localhost:7777). The default username/password is: admin/admin

### Next, [visit the Grafana dashboard] > Connection > [Add new connection](http://localhost:7777/connections/add-new-connection) > and select the Loki service we created earlier.
![add new connection step 1](https://blog.markkulab.net/content/markku/posts/from-installation-to-implementation-grafana-loki-nextjs-logging-guide/images/add-new-connection-1.png)![add new connection step 2](https://blog.markkulab.net/content/markku/posts/from-installation-to-implementation-grafana-loki-nextjs-logging-guide/images/add-new-connection-2.png)

### Now you can use the Explore feature in the dashboard to query the log entry we just wrote. You must include at least one filter condition, or the query will return no results.
![search result](https://blog.markkulab.net/content/markku/posts/from-installation-to-implementation-grafana-loki-nextjs-logging-guide/images/search-result.png)

### Note: Grafana actually supports many databases and services as data sources, such as MySQL and Jira. You can easily read data from them to create charts.
![kind of connections](https://blog.markkulab.net/content/markku/posts/from-installation-to-implementation-grafana-loki-nextjs-logging-guide/images/kind-of-connections.png)

## Application Integration
### Integrating Loki in Next.js
Next, install the required packages in your Next.js backend:
```
npm install winston winston-loki --save
```

### Create a `logger.ts` file
```
import winston from 'winston';
import LokiTransport from 'winston-loki';

const logger = winston.createLogger({
  transports: [
    new LokiTransport({
      host: 'http://localhost:3100',
      labels: { app: 'nextjs-app' },
      json: true,
    }),
  ],
});

export default logger;
```
To use it in a page:
```
import logger from '@/lib/log/loki-log';
logger.info('API request received', { endpoint: 'https://www.abc.com' });
```

### Frontend Application: Writing Logs via `fetch`

```
const LogLevel = {
  Information: "info",
  Debug: "debug",
  Warning: "warn",
  Error: "error",
};

async function clientLog(message, level = LogLevel.Information, extraLabels = {}) {
  if (!message) return;

  const timestamp = `${Date.now()}000000`; // 將毫秒級時間轉為納秒級
  const logData = {
    streams: [
      {
        stream: {
          app: "frontend-app",
          level: level,
          ...extraLabels, // 額外的標籤，例如用於區分不同頁面或功能
        },
        values: [
          [timestamp, message]
        ]
      }
    ]
  };

  try {
    const response = await fetch(LOKI_URL, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        // "Authorization": "Bearer YOUR_TOKEN" // 如果 Loki 設置了 Token 驗證，啟用此行
      },
      body: JSON.stringify(logData),
    });

    if (!response.ok) {
      console.error("Failed to send log to Loki:", response.statusText);
    }
  } catch (error) {
    console.error("Error sending log to Loki:", error);
  }
}
```

```
// 發送信息級別的日誌
clientLog("This is an informational message", LogLevel.Information, { page: "home" });

// 發送錯誤級別的日誌
clientLog("An error occurred", LogLevel.Error, { page: "checkout", userId: 12345 });

```
## Note: If you need to add a token to Loki, the simplest way is to add token validation when forwarding requests through Nginx.
```
server {
    listen 80;
    location /loki/ {
        proxy_pass http://localhost:3100; # Loki Url
        proxy_set_header Authorization "Bearer YOUR_TOKEN"; # 令牌
        # 可根据需求限制访问的 IP、路径等
        if ($http_authorization != "Bearer YOUR_TOKEN") {
            return 403; # 拒绝访问
        }
    }
}
```
## References
* [Official Website](https://grafana.com/docs/)
* [Reference 1](https://yiichenhi.medium.com/grafana-%E5%B0%87%E8%B3%87%E6%96%99%E8%A6%96%E8%A6%BA%E5%8C%96-%E7%B0%A1%E6%98%93%E7%9A%84%E4%BB%8B%E7%B4%B9%E8%88%87%E6%93%8D%E4%BD%9C-4af05a0f4d8c)

---

## About this article and its author

Originally published on [Mark Ku's Tech Notes](https://blog.markkulab.net/en/post/from-installation-to-implementation-grafana-loki-nextjs-logging-guide)

License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — when reusing or quoting, credit the author and link back to the original

### About the author

**[Mark Ku](https://blog.markkulab.net/en/author/mark-ku)** — Software Solution Provider

- 10+ years senior software engineer, now an AI Builder
- Focused on large-platform architecture — North-American e-commerce, AI SaaS subscription billing
- Combining AI Agents and automation to build evolvable product foundations

### Free tools built by the author

All of these are free to use:

- [Free PDF Sign Tool](https://blog.markkulab.net/en/tools/pdf-sign): Online PDF sign tool — draw, type, or upload a signature, then drag, resize, and download. Everything runs in your browser; nothing is uploaded.
- [VS Code Refactory](https://blog.markkulab.net/en/tools/refactory): Refactory is a VS Code refactoring extension: 34 actions plus a 37-rule code-smell inspection layer with a Code Health dashboard, across 18 languages, backed by 534 tests. It learns your repo's conventions: where interfaces live, where DI is registered, whether 'use client' belongs. It ranks files by git churn × complexity so you know what to fix first, and hands any smell to the Claude Code already on your machine. Free to use, and your source never leaves your computer.
- [DB-Kit Database Manager](https://blog.markkulab.net/en/tools/db-kit): DB-Kit is a lightweight, cross-platform database manager built with Tauri + Rust + React. Manage MySQL, MariaDB, PostgreSQL, SQL Server, Oracle, SQLite, MongoDB, Redis, Kafka, Elasticsearch and RabbitMQ from one consistent interface: passwords encrypted in the OS keychain, SSH tunnels, full CRUD, a visual query builder, stacked multi-statement result sets, cross-connection data transfer and compare/sync, Excel / CSV import & export, visualized execution plans, ER diagrams, scheduled backups, SQL stress testing with p50–p99 latency percentiles, a 15-rule SQL review engine, Kafka message browsing with monitoring & alerts, a bilingual UI (Traditional Chinese / English), a built-in AI assistant (natural-language SQL, AI review and tuning advice) and the dbk CLI. Free and open source (MIT), with installers for Windows, macOS and Linux.
- [VS Code Super Mermaid](https://blog.markkulab.net/en/tools/super-mermaid): Super Mermaid is a VS Code extension for beautiful Mermaid diagrams out of the box: auto-colored live preview, mouse pan & zoom, high-res PNG / SVG export, 21 templates and multiple themes. Free and open source (MIT).
- [React Super Mermaid](https://blog.markkulab.net/en/tools/react-super-mermaid): react-super-mermaid is an open-source React component library: render beautiful Mermaid diagrams with a single <MermaidViewer>, with built-in colorful / sketch themes, pan & zoom, in-diagram search, and high-res SVG / PNG export. Lightweight, SSR-safe, fully typed. Free and open source (MIT).
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/en/tools/jira-super-mermaid): An Atlassian Forge app: write Mermaid syntax directly inside a Jira issue or a Confluence page and get flowcharts, sequence diagrams, state machines and Gantt charts. 11 diagram types, SVG / PNG export, light and dark themes, full CJK support. Runs on Atlassian: your diagrams live in your own site and the app calls no third-party service. Free, coming soon to the Atlassian Marketplace.
- [Mermaid Live Preview](https://blog.markkulab.net/en/tools/mermaid-preview): Write Mermaid in your browser, see it render instantly, and share the whole diagram as a single link. No sign-up, nothing uploaded to a server, and mermaid.live share links work as-is.
- [React Intl Phone Number](https://blog.markkulab.net/en/tools/react-intl-phone-number): react-intl-phone-number is an open-source React component: framework-agnostic and antd-free, with E.164 in/out, a searchable flag / country-code dropdown, configurable validation levels (strict / mobile-strict / loose), themeable CSS, and i18n — phone logic powered by google-libphonenumber. Lightweight and fully typed. Free and open source (MIT).
- [Uptime Kuma Cluster](https://blog.markkulab.net/en/tools/uptime-kuma-cluster): Turn single-node Uptime Kuma into a highly available cluster: OpenResty + Lua smart load balancing, shared MariaDB state, health checks and automatic failover, plus cluster-management REST APIs. One Docker Compose command to start. Free and open source (MIT).
- [Special Education](https://blog.markkulab.net/en/education): Learning materials crafted for special education students

### Daily podcasts

- [Mark's Tech Insights — Daily AI News](https://blog.markkulab.net/en/category/tech-news): Daily curated AI and tech trends. Catch the latest developments via audio summaries — covering AI applications, software architecture, DevOps, and engineering practice. — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/en/category/ai-stock-chat): Every trading day, an AI-analyzed take on the Taiwan stock market, delivered as a two-host conversation covering the session and the next-day outlook. — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml
- [開源好物週報](https://blog.markkulab.net/en/category/open-source-weekly): A weekly two-host pick of free open-source tools surfaced from real Hacker News, GitHub, and Reddit buzz — what pain they solve and the fastest way to get started. — RSS: https://blog.markkulab.net/open-source-weekly/feed.xml

### Newsletter

[Subscribe to the newsletter](https://blog.markkulab.net/en/subscribe) — Be the first to know about new posts. No spam, unsubscribe anytime.
