Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计异常

structured-logging结构化日志记录

Agent Skill

structured-logging 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

606

周安装

25

GitHub Stars

8

下载量

198
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:structured-logging(结构化日志记录)
来源仓库:https://github.com/phrazzld/claude-config
仓库路径:skills/structured-logging
安装命令:
npx skills add https://github.com/phrazzld/claude-config --skill structured-logging
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/phrazzld/claude-config --skill structured-logging

简介

structured-logging 用于处理 GitHub 仓库和代码协作信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中整理 Issue 或 PR。
  • 通过 GitHub 安装,建议确认是否会触发文件读写。
  • 维护状态和权限范围需结合原始 README 进一步核验。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Structured Logging

Best practices for production-ready logging in Node.js applications using Pino and structured JSON output.

Philosophy

Logs are data, not text. Structured logging treats every log entry as a queryable data point, enabling powerful analysis, alerting, and debugging in production.

Three core principles:

  1. Machine-readable first: JSON structure enables programmatic querying
  2. Context-rich: Include all relevant metadata (correlation IDs, user IDs, request info)
  3. Security-conscious: Never log sensitive data (passwords, tokens, PII)

Why Pino

Pino is the recommended logging library for Node.js (2025):

  • 5x faster than Winston: Minimal CPU overhead, async by default
  • Structured JSON: Every log is a JSON object, no string templates
  • Low latency: Critical for high-throughput applications
  • Async transports: Heavy operations (file writes, network calls) happen in worker threads
  • Child loggers: Easy context propagation
  • Redaction built-in: Automatic sensitive data removal

Performance Comparison

LibraryLogs/SecondCPU UsageMemory
Pino50,000+2-4%~45MB
Winston~10,00010-15%~180MB
Bunyan~15,0008-12%~150MB

Installation & Setup

# Install Pino and pretty-printing for development
pnpm add pino
pnpm add -D pino-pretty

Basic Configuration

// lib/logger.ts
import pino from 'pino'

const isDevelopment = process.env.NODE_ENV === 'development'

export const logger = pino({
  level: process.env.LOG_LEVEL || 'info',

  // Use pretty printing in development, JSON in production
  transport: isDevelopment
    ? {
        target: 'pino-pretty',
        options: {
          colorize: true,
          translateTime: 'SYS:standard',
          ignore: 'pid,hostname',
        },
      }
    : undefined,

  // Base context included in every log
  base: {
    env: process.env.NODE_ENV || 'development',
    revision: process.env.VERCEL_GIT_COMMIT_SHA || 'local',
  },

  // Format timestamps as ISO 8601
  timestamp: pino.stdTimeFunctions.isoTime,

  // Redact sensitive fields automatically
  redact: {
    paths: [
      'password',
      'passwordHash',
      'secret',
      'apiKey',
      'token',
      'accessToken',
      'refreshToken',
      'authorization',
      'cookie',
      'req.headers.authorization',
      'req.headers.cookie',
      '*.password',
      '*.passwordHash',
      '*.secret',
      '*.apiKey',
      '*.token',
    ],
    censor: '[REDACTED]',
  },
})

// Export type for use in application
export type Logger = typeof logger

Log Levels

Pino supports six log levels (from lowest to highest):

logger.trace('Extremely detailed debugging')  // Level 10
logger.debug('Detailed debugging')            // Level 20
logger.info('General information')            // Level 30
logger.warn('Warning, non-critical issue')    // Level 40
logger.error('Error, requires attention')     // Level 50
logger.fatal('Fatal error, app cannot continue') // Level 60

When to use each level:

  • trace: Function entry/exit, loop iterations (extremely verbose)
  • debug: Variable values, conditional branches, algorithm steps
  • info: HTTP requests, user actions, state changes, startup/shutdown
  • warn: Deprecated API usage, retry attempts, degraded performance
  • error: Exceptions caught, failed operations, data validation errors
  • fatal: Database connection lost, critical service unavailable, unrecoverable errors

Production recommendation: Set LOG_LEVEL=info by default, use debug or trace only when debugging specific issues.

Child Loggers (Context Propagation)

Create child loggers to add context that persists across multiple log statements:

// Without child logger (repetitive)
logger.info({ userId: '123', requestId: 'abc' }, 'User logged in')
logger.info({ userId: '123', requestId: 'abc' }, 'Profile fetched')
logger.info({ userId: '123', requestId: 'abc' }, 'Settings updated')

// With child logger (clean)
const requestLogger = logger.child({ userId: '123', requestId: 'abc' })
requestLogger.info('User logged in')
requestLogger.info('Profile fetched')
requestLogger.info('Settings updated')

Middleware Pattern (Express/Next.js)

// middleware/logging.ts
import { v4 as uuidv4 } from 'uuid'
import { logger } from '@/lib/logger'
import type { NextRequest } from 'next/server'

export function createRequestLogger(req: NextRequest) {
  // Generate correlation ID for request tracing
  const correlationId = req.headers.get('x-correlation-id') || uuidv4()

  // Create child logger with request context
  return logger.child({
    correlationId,
    method: req.method,
    path: req.nextUrl.pathname,
    userAgent: req.headers.get('user-agent'),
    ip: req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip'),
  })
}

// Usage in API route
export async function GET(req: NextRequest) {
  const log = createRequestLogger(req)

  log.info('Processing request')

  try {
    const data = await fetchData()
    log.info({ dataCount: data.length }, 'Data fetched successfully')
    return Response.json(data)
  } catch (error) {
    log.error({ error }, 'Failed to fetch data')
    return Response.json({ error: 'Internal error' }, { status: 500 })
  }
}

Structured Logging Patterns

✅ Good: Structured Fields

// Queryable, analyzable
logger.info({
  event: 'user_login',
  userId: user.id,
  email: user.email,
  provider: 'google',
  duration: 150,
}, 'User authenticated')

// Easy queries:
// - All Google logins: event='user_login' AND provider='google'
// - Slow logins: event='user_login' AND duration > 1000
// - Specific user: event='user_login' AND userId='123'

❌ Bad: String Templates

// Not queryable, hard to parse
logger.info(`User ${user.email} logged in via ${provider} in ${duration}ms`)

// Cannot easily query by provider or filter by duration

Error Logging

// ✅ Good: Include error object with structured context
try {
  await riskyOperation()
} catch (error) {
  logger.error({
    error,
    operation: 'riskyOperation',
    userId: user.id,
    retryCount: 3,
  }, 'Operation failed after retries')
}

// ❌ Bad: Lose stack trace and context
try {
  await riskyOperation()
} catch (error) {
  logger.error(`Operation failed: ${error.message}`)
}

Note on Error serialization: Pino handles Error objects natively, but JSON.stringify(new Error("msg")) returns {} because message, name, stack are non-enumerable. For custom loggers, manually extract:

function serializeError(err: unknown): Record<string, unknown> {
  if (err instanceof Error) {
    return { name: err.name, message: err.message, stack: err.stack };
  }
  return { value: String(err) };
}

Performance Logging

// Track operation duration
const startTime = Date.now()

try {
  const result = await fetchFromDatabase(query)
  const duration = Date.now() - startTime

  logger.info({
    event: 'database_query',
    query: query.type,
    duration,
    resultCount: result.length,
  }, 'Query completed')

  // Alert if slow
  if (duration > 1000) {
    logger.warn({
      event: 'slow_query',
      query: query.type,
      duration,
    }, 'Database query exceeded threshold')
  }

  return result
} catch (error) {
  logger.error({
    error,
    event: 'database_error',
    query: query.type,
    duration: Date.now() - startTime,
  }, 'Query failed')
  throw error
}

Correlation IDs (Request Tracing)

Correlation IDs enable tracing a single request through multiple services and log statements.

// middleware/correlation.ts
import { v4 as uuidv4 } from 'uuid'

export function correlationMiddleware(req: Request, res: Response, next: NextFunction) {
  // Extract or generate correlation ID
  const correlationId = req.headers['x-correlation-id'] || uuidv4()

  // Add to response headers for client
  res.setHeader('x-correlation-id', correlationId)

  // Attach logger with correlation ID to request
  req.log = logger.child({ correlationId })

  next()
}

// Usage in route
app.get('/api/users', async (req, res) => {
  req.log.info('Fetching users')

  const users = await fetchUsers()
  req.log.info({ count: users.length }, 'Users fetched')

  res.json(users)
})

// All logs will include the same correlationId:
// {"level":"info","correlationId":"abc-123","msg":"Fetching users"}
// {"level":"info","correlationId":"abc-123","count":42,"msg":"Users fetched"}

Sensitive Data Redaction

Critical security practice: Never log sensitive information.

Automatic Redaction (configured in setup)

// Pino automatically redacts these fields (from setup above)
logger.info({
  user: {
    email: 'user@example.com',
    password: 'secret123',  // Will be [REDACTED]
  },
  apiKey: 'sk_live_123',    // Will be [REDACTED]
}, 'User data processed')

// Output:
// {
//   "user": {
//     "email": "user@example.com",
//     "password": "[REDACTED]"
//   },
//   "apiKey": "[REDACTED]",
//   "msg": "User data processed"
// }

Manual Redaction for Dynamic Fields

// Utility function for safe logging
function sanitizeForLogging<T extends Record<string, any>>(obj: T): T {
  const sensitivePatterns = [
    /password/i,
    /secret/i,
    /token/i,
    /key/i,
    /authorization/i,
  ]

  const sanitized = { ...obj }

  for (const key in sanitized) {
    if (sensitivePatterns.some(pattern => pattern.test(key))) {
      sanitized[key] = '[REDACTED]'
    }
  }

  return sanitized
}

// Usage
logger.info(sanitizeForLogging(userData), 'User updated')

Convex-Specific Logging

Convex functions run in a managed environment with built-in logging, but structured logging still applies:

// convex/users.ts
import { query } from './_generated/server'
import { v } from 'convex/values'

export const getUser = query({
  args: { userId: v.id('users') },
  handler: async (ctx, args) => {
    // Use console with structured data
    console.info({
      operation: 'getUser',
      userId: args.userId,
      timestamp: Date.now(),
    })

    try {
      const user = await ctx.db.get(args.userId)

      if (!user) {
        console.warn({
          operation: 'getUser',
          userId: args.userId,
          result: 'not_found',
        })
        return null
      }

      console.info({
        operation: 'getUser',
        userId: args.userId,
        result: 'success',
      })

      return user
    } catch (error) {
      console.error({
        operation: 'getUser',
        userId: args.userId,
        error: error.message,
      })
      throw error
    }
  },
})

Note: Convex console.log/info/error are automatically structured in the dashboard. Use objects instead of strings for better filtering.

Centralization & Observability

In production, centralize logs to a log aggregation service:

Option 1: Datadog (Recommended for Enterprise)

// lib/logger.ts
import pino from 'pino'

const logger = pino({
  // ... base config

  transport: {
    target: 'pino-datadog-transport',
    options: {
      apiKey: process.env.DATADOG_API_KEY,
      service: 'my-app',
      env: process.env.NODE_ENV,
      tags: ['team:engineering', 'project:webapp'],
    },
  },
})

Option 2: Graylog (Self-Hosted)

import pino from 'pino'

const logger = pino({
  transport: {
    target: 'pino-socket',
    options: {
      address: process.env.GRAYLOG_HOST,
      port: 12201,
      mode: 'udp',
    },
  },
})

Option 3: Vercel Log Drains (for Next.js on Vercel)

Vercel automatically collects logs and can forward to:

  • Datadog
  • LogDNA
  • Logtail
  • New Relic
  • Sentry
  • Custom HTTPS endpoints

Configure in Vercel Dashboard → Project → Settings → Log Drains

Querying Logs

With centralized structured logs, you can query efficiently:

# Datadog query
service:my-app AND env:production AND level:error AND @userId:123

# Find slow database queries
service:my-app AND event:database_query AND duration > 1000

# Track user journey
service:my-app AND @correlationId:abc-123-def

Testing & Development

Development: Pretty Printing

# Pretty output for development
NODE_ENV=development pnpm dev

# Raw JSON for testing centralization
NODE_ENV=production pnpm dev

Testing: Log Capture

// test/logger.test.ts
import { describe, it, expect, vi } from 'vitest'
import { logger } from '@/lib/logger'

describe('Logger', () => {
  it('redacts sensitive fields', () => {
    const logSpy = vi.spyOn(logger, 'info')

    logger.info({
      email: 'user@example.com',
      password: 'secret',
    }, 'User data')

    expect(logSpy).toHaveBeenCalledWith(
      expect.objectContaining({
        email: 'user@example.com',
        password: '[REDACTED]',
      }),
      'User data'
    )
  })
})

Best Practices Summary

Do ✅

  • Use structured JSON: {userId: '123', action: 'login'} not "User 123 logged in"
  • Include context: Add all relevant fields (IDs, timestamps, metadata)
  • Use correlation IDs: Track requests across services
  • Redact sensitive data: Passwords, tokens, PII automatically filtered
  • Log at appropriate levels: info for normal flow, error for failures
  • Use child loggers: Add context once, reuse across log statements
  • Centralize in production: Send logs to Datadog/Graylog/ELK
  • Query your logs: Use structured fields for powerful analysis

Don't ❌

  • Don't use string templates: Breaks queryability
  • Don't log sensitive data: Passwords, tokens, credit cards, SSNs
  • Don't log in tight loops: Excessive logs hurt performance
  • Don't ignore log levels: Trace/debug should be off in production
  • Don't concatenate error messages: Log full error object with stack
  • Don't use console.log in production: Use proper logging library
  • Don't skip correlation IDs: Makes debugging multi-service flows impossible

Quick Setup Checklist

For a new Node.js/Next.js project:

  • Install Pino: pnpm add pino pino-pretty
  • Create logger singleton in lib/logger.ts
  • Configure redaction for sensitive fields
  • Set up correlation ID middleware
  • Create child logger pattern for requests
  • Configure pretty printing for development
  • Set up log transport for production (Datadog/Graylog)
  • Add environment variable: LOG_LEVEL
  • Test redaction with unit tests
  • Document logging patterns in project README

Philosophy

"Logs are the voice of your production application."

Structured logging transforms logs from debug statements into queryable data. In production, logs enable:

  • Debugging: Trace requests, find errors, understand behavior
  • Monitoring: Track metrics, detect anomalies, set alerts
  • Analytics: Understand user behavior, measure performance
  • Security: Detect attacks, audit access, investigate incidents

Invest in logging infrastructure early. The cost is minimal; the value is immense.


When agents implement logging, they should:

  • Default to Pino for Node.js applications (5x faster than Winston)
  • Use structured JSON fields, not string templates
  • Include correlation IDs for request tracing
  • Redact sensitive fields automatically
  • Use child loggers for context propagation
  • Log at appropriate levels (info for normal, error for failures)
  • Centralize logs in production (Datadog, Graylog, or Vercel Log Drains)
  • Never log passwords, tokens, API keys, or PII

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.77%
按下载量换算71

Claude

31.53%
按下载量换算62

Cursor

20.1%
按下载量换算40

Gemini CLI

9.23%
按下载量换算18

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills