Token导航 LogoToken导航TokenDH.com
开发external-servicegithub未标认证来源可访问许可证需确认审计通过

python-loggingPython logging 测试

Agent Skill

用于辅助 Python 项目开发、测试、依赖管理和常见框架工作流。它适合让 Agent 阅读 Python 代码、定位测试问题、整理运行命令、生成脚本或分析数据处理逻辑。使用时需要确认项目虚拟环境、依赖版本和测试入口;涉及执行脚本、读写文件、访问数据库或调用外部 API 时,应先明确运行目录和输入输出范围,避免误改生产数据。

总安装

546

周安装

23

GitHub Stars

12

下载量

191
CodexClaudeCursorGemini CLI

安装说明

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

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill python-logging

简介

用于辅助 Python 项目开发、测试与依赖管理。

  • 支持代码阅读、运行命令整理和数据处理逻辑分析。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。
  • 需确认虚拟环境、依赖版本和测试入口后再执行操作。
  • 涉及脚本执行或文件读写时应明确目录与数据边界。
  • python-logging 属于开发类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Python Logging

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: python for comprehensive documentation.

Standard Library (logging)

Basic Setup

import logging

# Configure root logger
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

# Get logger for module
logger = logging.getLogger(__name__)

# Usage
logger.debug('Debug message')
logger.info('Info message')
logger.warning('Warning message')
logger.error('Error message')
logger.critical('Critical message')

Advanced Configuration

import logging
import logging.handlers
import sys

def setup_logging(level: str = 'INFO') -> None:
    """Configure application logging."""

    # Create formatter
    formatter = logging.Formatter(
        fmt='%(asctime)s | %(levelname)-8s | %(name)s:%(lineno)d | %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )

    # Console handler
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setFormatter(formatter)
    console_handler.setLevel(logging.DEBUG)

    # File handler with rotation
    file_handler = logging.handlers.RotatingFileHandler(
        filename='logs/app.log',
        maxBytes=100 * 1024 * 1024,  # 100MB
        backupCount=5,
        encoding='utf-8'
    )
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)

    # Configure root logger
    root_logger = logging.getLogger()
    root_logger.setLevel(getattr(logging, level.upper()))
    root_logger.addHandler(console_handler)
    root_logger.addHandler(file_handler)

    # Reduce noise from third-party libraries
    logging.getLogger('urllib3').setLevel(logging.WARNING)
    logging.getLogger('httpx').setLevel(logging.WARNING)

Log Levels

LevelNumericUsage
CRITICAL50System unusable
ERROR40Error conditions
WARNING30Warning conditions
INFO20Normal operations
DEBUG10Debug information
NOTSET0Inherit from parent

Exception Logging

try:
    result = process_data(data)
except ValueError as e:
    logger.error('Invalid data format: %s', e)
except Exception:
    logger.exception('Unexpected error processing data')  # Includes traceback
    raise

Extra Context

# Using extra parameter
logger.info('User logged in', extra={'user_id': user.id, 'ip': request.ip})

# Custom LoggerAdapter for consistent context
class ContextLogger(logging.LoggerAdapter):
    def process(self, msg, kwargs):
        extra = kwargs.get('extra', {})
        extra.update(self.extra)
        kwargs['extra'] = extra
        return msg, kwargs

logger = ContextLogger(logging.getLogger(__name__), {'request_id': request_id})
logger.info('Processing request')

Structlog (Structured Logging)

Installation

pip install structlog

Basic Setup

import structlog

structlog.configure(
    processors=[
        structlog.stdlib.filter_by_level,
        structlog.stdlib.add_logger_name,
        structlog.stdlib.add_log_level,
        structlog.stdlib.PositionalArgumentsFormatter(),
        structlog.processors.TimeStamper(fmt='iso'),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
        structlog.processors.UnicodeDecoder(),
        structlog.processors.JSONRenderer()  # or ConsoleRenderer() for dev
    ],
    wrapper_class=structlog.stdlib.BoundLogger,
    context_class=dict,
    logger_factory=structlog.stdlib.LoggerFactory(),
    cache_logger_on_first_use=True,
)

logger = structlog.get_logger()

Usage

# Basic logging
logger.info('Server started', port=8000, host='0.0.0.0')

# Bind context
log = logger.bind(user_id=user.id, request_id=request_id)
log.info('Processing request')
log.info('Request completed', status=200, duration_ms=45)

# Exception logging
try:
    process()
except Exception:
    logger.exception('Processing failed', order_id=order.id)

Output (JSON)

{
  "event": "Processing request",
  "user_id": 123,
  "request_id": "abc-123",
  "timestamp": "2025-01-15T10:30:00.000000Z",
  "level": "info",
  "logger": "myapp.services"
}

Development vs Production

import structlog
import sys

def configure_logging(env: str = 'development'):
    shared_processors = [
        structlog.stdlib.add_log_level,
        structlog.stdlib.add_logger_name,
        structlog.processors.TimeStamper(fmt='iso'),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
    ]

    if env == 'production':
        # JSON output for log aggregation
        processors = shared_processors + [
            structlog.processors.JSONRenderer()
        ]
    else:
        # Pretty console output for development
        processors = shared_processors + [
            structlog.dev.ConsoleRenderer(colors=True)
        ]

    structlog.configure(
        processors=processors,
        wrapper_class=structlog.stdlib.BoundLogger,
        context_class=dict,
        logger_factory=structlog.stdlib.LoggerFactory(),
        cache_logger_on_first_use=True,
    )

FastAPI Integration

Middleware for Request Logging

import time
import uuid
from fastapi import FastAPI, Request
import structlog

app = FastAPI()
logger = structlog.get_logger()

@app.middleware('http')
async def logging_middleware(request: Request, call_next):
    request_id = str(uuid.uuid4())
    start_time = time.perf_counter()

    # Bind context for this request
    structlog.contextvars.clear_contextvars()
    structlog.contextvars.bind_contextvars(
        request_id=request_id,
        method=request.method,
        path=request.url.path,
    )

    logger.info('Request started')

    response = await call_next(request)

    duration_ms = (time.perf_counter() - start_time) * 1000
    logger.info(
        'Request completed',
        status_code=response.status_code,
        duration_ms=round(duration_ms, 2)
    )

    response.headers['X-Request-ID'] = request_id
    return response

Dependency Injection

from fastapi import Depends
import structlog

def get_logger() -> structlog.stdlib.BoundLogger:
    return structlog.get_logger()

@app.get('/users/{user_id}')
async def get_user(
    user_id: int,
    logger: structlog.stdlib.BoundLogger = Depends(get_logger)
):
    logger = logger.bind(user_id=user_id)
    logger.info('Fetching user')
    # ...

Django Integration

settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{asctime} {levelname} {name} {message}',
            'style': '{',
        },
        'json': {
            '()': 'pythonjsonlogger.jsonlogger.JsonFormatter',
            'format': '%(asctime)s %(levelname)s %(name)s %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django.log',
            'maxBytes': 100 * 1024 * 1024,
            'backupCount': 5,
            'formatter': 'json',
        },
    },
    'root': {
        'handlers': ['console', 'file'],
        'level': 'INFO',
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': False,
        },
        'django.db.backends': {
            'level': 'WARNING',  # Reduce SQL noise
        },
    },
}

Best Practices

DO

# Use module-level loggers
logger = logging.getLogger(__name__)

# Use lazy formatting
logger.info('User %s performed %s', user_id, action)

# Include context
logger.info('Order processed', extra={'order_id': order.id, 'total': total})

# Log exceptions with traceback
logger.exception('Failed to process order')

DON'T

# Don't use f-strings (evaluated even when level is disabled)
logger.debug(f'Processing {expensive_computation()}')  # BAD

# Don't log sensitive data
logger.info('Login: user=%s, password=%s', user, password)  # BAD!

# Don't use print() for logging
print(f'Error: {error}')  # BAD - use logger.error()

Sensitive Data Handling

import re

class SensitiveDataFilter(logging.Filter):
    PATTERNS = [
        (re.compile(r'password["\']?\s*[:=]\s*["\']?[^"\'}\s]+'), 'password=***'),
        (re.compile(r'token["\']?\s*[:=]\s*["\']?[^"\'}\s]+'), 'token=***'),
    ]

    def filter(self, record):
        message = record.getMessage()
        for pattern, replacement in self.PATTERNS:
            message = pattern.sub(replacement, message)
        record.msg = message
        record.args = ()
        return True

# Add filter to handler
handler.addFilter(SensitiveDataFilter())

When NOT to Use This Skill

  • structlog-specific questions: Use structlog skill for detailed configuration
  • Node.js/Java projects: Use language-appropriate logging skills
  • Simple print debugging: print() is fine for quick scripts
  • Third-party library internals: Consult library-specific docs
  • Log analysis: Use log-analyzer MCP server instead

Anti-Patterns

Anti-PatternWhy It's BadSolution
Using print() for loggingNo control, no filtering, no formattingUse logging module
f-strings in log messagesAlways evaluated, performance hitUse lazy formatting: logger.info('User %s', user_id)
Not using module-level loggersLoses context about log sourceUse logger = logging.getLogger(__name__)
Root logger configuration in librariesAffects all applicationsOnly configure in main application
Logging exceptions without tracebackLoses debugging contextUse logger.exception() in except blocks
Not rotating log filesDisk fills upUse RotatingFileHandler or TimedRotatingFileHandler

Quick Troubleshooting

IssueCauseSolution
Logs not appearingLog level too highCheck logger.setLevel() and handler levels
Duplicate log messagesMultiple handlers on same loggerCheck handler configuration, set propagate=False
No traceback in logsUsing logger.error() instead of exception()Use logger.exception() in except blocks
Third-party library spamNoisy library logsSet specific logger levels: logging.getLogger('urllib3').setLevel(WARNING)
Performance issuesToo many handlers or formattersSimplify configuration, use appropriate log levels
Missing contextNot using extra parameterUse logger.info('msg', extra={'key': value}) or LoggerAdapter

Reference

适合场景

01

用户想查找某类 Agent Skill 时

02

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

03

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

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

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

能力 4

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

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

平台分布

Codex

36.86%
按下载量换算70

Claude

29.9%
按下载量换算57

Cursor

20.14%
按下载量换算38

Gemini CLI

10.33%
按下载量换算20

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

external-service

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

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

来源信息

继续浏览同类 Skills