[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M79GRSR9RZBGFSHY8F0G4Z95":3,"skill-same:01M79GRSR9RZBGFSHY8F0G4Z95":46},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":26,"repositoryHtmlUrl":27,"repositoryHomepageUrl":28,"ownerHtmlUrl":29,"ownerBlogUrl":6,"ownerDescription":30,"updatedAt":31,"install":32,"resources":45},"01M79GRSR9RZBGFSHY8F0G4Z95","scaffold-observability",null,"Configure ArchiPy 5.x OpenTelemetry traces, metrics, logs, and instrumentation. Use for \"add tracing\u002Fmetrics\u002FOTel\", \"Prometheus\u002FPushgateway\", or migrating off Sentry, Elastic APM, or old Prometheus.","SyntaxArc\u002Farchipy-plugin","SyntaxArc","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F199446442?v=4","01M79GPX74Y0R3C1MTXHETZZYF","01M79GPX7S33ZRJ5935EQ3JRPN",3,"MIT","https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-observability\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: scaffold-observability\ndescription: >-\n  Configure ArchiPy 5.x OpenTelemetry traces, metrics, logs, and instrumentation. Use\n  for \"add tracing\u002Fmetrics\u002FOTel\", \"Prometheus\u002FPushgateway\", or migrating off Sentry,\n  Elastic APM, or old Prometheus.\n---\n\n# Scaffold ArchiPy OpenTelemetry\n\n## Read first\n\nRead these plugin rules in full before generating files (paths relative to this skill directory; Claude Code: `${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Frules\u002F`):\n\n- `..\u002F..\u002Frules\u002Fconfig-and-di.mdc`\n\n## Before writing files\n\n1. Inspect `pyproject.toml`\u002F`uv.lock`, `AppConfig`, bootstrap order, app transports, adapters, and `.env.example`.\n2. Infer required instrumentation extras from the installed stack.\n3. Ask only for unresolved choices: enabled signals, metrics exporter (`otlp` \u002F `pull` \u002F\n   `pushgateway`), OTLP endpoint\u002Fprotocol or Pushgateway URL, service name, sampling ratio,\n   and log level.\n4. Preserve existing config\u002Fbootstrap. Never write collector credentials or OTLP headers with secret values.\n\n## Install only matching extras\n\n| Stack | Extra |\n|-------|-------|\n| Core OTLP traces, metrics, logs | `otel` |\n| FastAPI | `otel` + `fastapi` (no separate extra) |\n| gRPC | `otel-grpc` |\n| SQLAlchemy | `otel-sqlalchemy` |\n| Redis | `otel-redis` |\n| Elasticsearch | `otel-elasticsearch` |\n| Kafka | `otel-kafka` |\n| ScyllaDB | `otel-scylladb` |\n| MinIO\u002Fbotocore | `otel-minio` |\n\nCombine required extras, for example:\n\n```bash\nuv add \"archipy[otel,fastapi,otel-sqlalchemy,otel-redis]\"\n```\n\nDo not use removed ArchiPy 4.x extras: `prometheus`, `sentry`, or `elastic-apm`.\n\n## Configure\n\nAdd non-secret defaults\u002Fdocumentation to `.env.example`:\n\n```bash\nOTEL__IS_ENABLED=true\nOTEL__SERVICE_NAME=my-service\nOTEL__OTLP_ENDPOINT=http:\u002F\u002Flocalhost:4317\nOTEL__PROTOCOL=grpc\nOTEL__TRACES_ENABLED=true\nOTEL__METRICS_ENABLED=true\nOTEL__METRICS_EXPORTER=otlp\n# Pull scrape: OTEL__METRICS_EXPORTER=pull\n# Pushgateway: OTEL__METRICS_EXPORTER=pushgateway\n# OTEL__METRICS_PUSHGATEWAY_URL=http:\u002F\u002Fpushgateway.monitoring:9091\nOTEL__METRICS_PULL_HOST=0.0.0.0\nOTEL__METRICS_PULL_PORT=8200\nOTEL__SYSTEM_METRICS_ENABLED=true\nOTEL__LOGS_ENABLED=true\nOTEL__LOGS_EXPORTER=console\nOTEL__TRACES_SAMPLE_RATIO=0.1\nOTEL__LOGS_LEVEL=WARNING\nOTEL__FASTAPI_EXCLUDED_URLS=health,docs,redoc,openapi.json\n```\n\nUse `BaseConfig.OTEL`; ArchiPy builds providers programmatically. Do not rely on OpenTelemetry SDK `OTEL_*`\nautoconfiguration. For `http\u002Fprotobuf`, use port 4318; ArchiPy appends `\u002Fv1\u002F{signal}` when the base endpoint has no path.\nSet `OTEL__METRICS_EXPORTER=pull` for scrape-only metrics. Set `OTEL__METRICS_EXPORTER=pushgateway`\nand `OTEL__METRICS_PUSHGATEWAY_URL` (job defaults to `SERVICE_NAME`) for Prometheus Pushgateway —\nno local `\u002Fmetrics` server. `otlp` pushes OTLP to a collector; do not confuse it with Pushgateway.\nIf pull scrape cannot bind, ArchiPy logs a warning and keeps traces\u002Flogs\u002Fmetrics providers.\nSet `OTEL__LOGS_EXPORTER=otlp` to push logs to a collector (default `console` writes INFO\u002FDEBUG to\nstdout and WARNING+ to stderr).\n\n## Initialize before adapters\n\nAfter `BaseConfig.set_global(config)` and before constructing the DI container\u002Fadapters:\n\n```python\nfrom archipy.configs.base_config import BaseConfig\nfrom archipy.helpers.utils.otel_utils import OtelUtils\n\nconfig = AppConfig()\nBaseConfig.set_global(config)\nOtelUtils.init_otel_if_needed(config)\ncontainer = ApplicationContainer()\n```\n\nInitialization is idempotent. AppUtils calls it again safely. Early initialization matters for SQLAlchemy engines,\nKafka clients, ScyllaDB sessions, and logs created during bootstrap.\n\n## Instrument application code\n\n- FastAPI: `AppUtils.create_fastapi_app(config)` with `archipy[otel,fastapi]`.\n- gRPC server: `create_grpc_app` \u002F `create_async_grpc_app` with `archipy[otel-grpc]`.\n  - Traces: contrib server interceptor when `OTEL.TRACES_ENABLED`.\n  - Metrics: ArchiPy `GrpcServerOtelMetricsInterceptor` \u002F\n    `AsyncGrpcServerOtelMetricsInterceptor` records `rpc.server.call.duration` when\n    `OTEL.METRICS_ENABLED` (works without traces).\n- Tuning (archipy >= 5.16.0): `OTEL.TRACES_SAMPLER`, `PROPAGATORS` (`b3`, `b3multi`; B3 ships in `archipy[otel]`),\n  `OTLP_COMPRESSION` (`none` by default), `SPAN_BATCH_*`, `RESOURCE_DETECTORS`; `USE_STANDARD_ENV` makes the standard\n  `OTEL_*` variables fill unset settings.\n- gRPC clients: `OtelUtils.grpc_client_interceptors()` \u002F `async_grpc_client_interceptors()`.\n- Traces: `trace_root`, `trace_span`, `async_trace_root`, `async_trace_span`, `trace_class`.\n- Metrics: `measure_duration`, `async_measure_duration`, `count_calls`, `async_count_calls`.\n- Exceptions: `BaseUtils.capture_exception` records on the current span.\n\nImport decorators from `archipy.helpers.decorators`. `measure_duration`, `count_calls`, `trace_span` and `trace_root` detect `async def`; the `async_*` twins remain.\nOnly capture non-sensitive argument names in trace attributes.\n\n## ArchiPy 4.x migration\n\n- `TracingUtils` → `OtelUtils`\n- `capture_transaction` \u002F `capture_span` → `trace_root` \u002F `trace_span` (+ async twins)\n- Prometheus\u002FSentry\u002FElastic APM config → `BaseConfig.OTEL`\n- Removed FastAPI rate-limit handler → `fastapi-redis-sdk`\n\n## Do not\n\n- Never commit OTLP credentials; no secrets in source, logs, or committed env files.\n\n## Verify\n\n1. Run the repository formatter\u002Flinter and import the bootstrap without starting long-lived servers.\n2. Confirm OTel initializes before adapter construction and AppUtils receives the same global\u002Finjected config.\n3. Test with in-memory exporters or `OtelUtils.configure_for_testing`; do not require a production collector.\n4. Confirm disabled signals no-op and no credentials appear in source, logs, or committed env files.\n5. Run the `archipy-reviewer` subagent on the changes and fix every **Must fix** finding it reports.\n6. Report extras, config keys, bootstrap changes, and commands run.\n\n## Docs\n\n- https:\u002F\u002Fsyntaxarc.github.io\u002FArchiPy\u002Ftutorials\u002Fobservability\u002F\n- https:\u002F\u002Fsyntaxarc.github.io\u002FArchiPy\u002Ftutorials\u002Fhelpers\u002Finterceptors\u002F\n","# Scaffold ArchiPy OpenTelemetry\n\n## Read first\n\nRead these plugin rules in full before generating files (paths relative to this skill directory; Claude Code: `${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Frules\u002F`):\n\n- `..\u002F..\u002Frules\u002Fconfig-and-di.mdc`\n\n## Before writing files\n\n1. Inspect `pyproject.toml`\u002F`uv.lock`, `AppConfig`, bootstrap order, app transports, adapters, and `.env.example`.\n2. Infer required instrumentation extras from the installed stack.\n3. Ask only for unresolved choices: enabled signals, metrics exporter (`otlp` \u002F `pull` \u002F\n   `pushgateway`), OTLP endpoint\u002Fprotocol or Pushgateway URL, service name, sampling ratio,\n   and log level.\n4. Preserve existing config\u002Fbootstrap. Never write collector credentials or OTLP headers with secret values.\n\n## Install only matching extras\n\n| Stack | Extra |\n|-------|-------|\n| Core OTLP traces, metrics, logs | `otel` |\n| FastAPI | `otel` + `fastapi` (no separate extra) |\n| gRPC | `otel-grpc` |\n| SQLAlchemy | `otel-sqlalchemy` |\n| Redis | `otel-redis` |\n| Elasticsearch | `otel-elasticsearch` |\n| Kafka | `otel-kafka` |\n| ScyllaDB | `otel-scylladb` |\n| MinIO\u002Fbotocore | `otel-minio` |\n\nCombine required extras, for example:\n\n```bash\nuv add \"archipy[otel,fastapi,otel-sqlalchemy,otel-redis]\"\n```\n\nDo not use removed ArchiPy 4.x extras: `prometheus`, `sentry`, or `elastic-apm`.\n\n## Configure\n\nAdd non-secret defaults\u002Fdocumentation to `.env.example`:\n\n```bash\nOTEL__IS_ENABLED=true\nOTEL__SERVICE_NAME=my-service\nOTEL__OTLP_ENDPOINT=http:\u002F\u002Flocalhost:4317\nOTEL__PROTOCOL=grpc\nOTEL__TRACES_ENABLED=true\nOTEL__METRICS_ENABLED=true\nOTEL__METRICS_EXPORTER=otlp\n# Pull scrape: OTEL__METRICS_EXPORTER=pull\n# Pushgateway: OTEL__METRICS_EXPORTER=pushgateway\n# OTEL__METRICS_PUSHGATEWAY_URL=http:\u002F\u002Fpushgateway.monitoring:9091\nOTEL__METRICS_PULL_HOST=0.0.0.0\nOTEL__METRICS_PULL_PORT=8200\nOTEL__SYSTEM_METRICS_ENABLED=true\nOTEL__LOGS_ENABLED=true\nOTEL__LOGS_EXPORTER=console\nOTEL__TRACES_SAMPLE_RATIO=0.1\nOTEL__LOGS_LEVEL=WARNING\nOTEL__FASTAPI_EXCLUDED_URLS=health,docs,redoc,openapi.json\n```\n\nUse `BaseConfig.OTEL`; ArchiPy builds providers programmatically. Do not rely on OpenTelemetry SDK `OTEL_*`\nautoconfiguration. For `http\u002Fprotobuf`, use port 4318; ArchiPy appends `\u002Fv1\u002F{signal}` when the base endpoint has no path.\nSet `OTEL__METRICS_EXPORTER=pull` for scrape-only metrics. Set `OTEL__METRICS_EXPORTER=pushgateway`\nand `OTEL__METRICS_PUSHGATEWAY_URL` (job defaults to `SERVICE_NAME`) for Prometheus Pushgateway —\nno local `\u002Fmetrics` server. `otlp` pushes OTLP to a collector; do not confuse it with Pushgateway.\nIf pull scrape cannot bind, ArchiPy logs a warning and keeps traces\u002Flogs\u002Fmetrics providers.\nSet `OTEL__LOGS_EXPORTER=otlp` to push logs to a collector (default `console` writes INFO\u002FDEBUG to\nstdout and WARNING+ to stderr).\n\n## Initialize before adapters\n\nAfter `BaseConfig.set_global(config)` and before constructing the DI container\u002Fadapters:\n\n```python\nfrom archipy.configs.base_config import BaseConfig\nfrom archipy.helpers.utils.otel_utils import OtelUtils\n\nconfig = AppConfig()\nBaseConfig.set_global(config)\nOtelUtils.init_otel_if_needed(config)\ncontainer = ApplicationContainer()\n```\n\nInitialization is idempotent. AppUtils calls it again safely. Early initialization matters for SQLAlchemy engines,\nKafka clients, ScyllaDB sessions, and logs created during bootstrap.\n\n## Instrument application code\n\n- FastAPI: `AppUtils.create_fastapi_app(config)` with `archipy[otel,fastapi]`.\n- gRPC server: `create_grpc_app` \u002F `create_async_grpc_app` with `archipy[otel-grpc]`.\n  - Traces: contrib server interceptor when `OTEL.TRACES_ENABLED`.\n  - Metrics: ArchiPy `GrpcServerOtelMetricsInterceptor` \u002F\n    `AsyncGrpcServerOtelMetricsInterceptor` records `rpc.server.call.duration` when\n    `OTEL.METRICS_ENABLED` (works without traces).\n- Tuning (archipy >= 5.16.0): `OTEL.TRACES_SAMPLER`, `PROPAGATORS` (`b3`, `b3multi`; B3 ships in `archipy[otel]`),\n  `OTLP_COMPRESSION` (`none` by default), `SPAN_BATCH_*`, `RESOURCE_DETECTORS`; `USE_STANDARD_ENV` makes the standard\n  `OTEL_*` variables fill unset settings.\n- gRPC clients: `OtelUtils.grpc_client_interceptors()` \u002F `async_grpc_client_interceptors()`.\n- Traces: `trace_root`, `trace_span`, `async_trace_root`, `async_trace_span`, `trace_class`.\n- Metrics: `measure_duration`, `async_measure_duration`, `count_calls`, `async_count_calls`.\n- Exceptions: `BaseUtils.capture_exception` records on the current span.\n\nImport decorators from `archipy.helpers.decorators`. `measure_duration`, `count_calls`, `trace_span` and `trace_root` detect `async def`; the `async_*` twins remain.\nOnly capture non-sensitive argument names in trace attributes.\n\n## ArchiPy 4.x migration\n\n- `TracingUtils` → `OtelUtils`\n- `capture_transaction` \u002F `capture_span` → `trace_root` \u002F `trace_span` (+ async twins)\n- Prometheus\u002FSentry\u002FElastic APM config → `BaseConfig.OTEL`\n- Removed FastAPI rate-limit handler → `fastapi-redis-sdk`\n\n## Do not\n\n- Never commit OTLP credentials; no secrets in source, logs, or committed env files.\n\n## Verify\n\n1. Run the repository formatter\u002Flinter and import the bootstrap without starting long-lived servers.\n2. Confirm OTel initializes before adapter construction and AppUtils receives the same global\u002Finjected config.\n3. Test with in-memory exporters or `OtelUtils.configure_for_testing`; do not require a production collector.\n4. Confirm disabled signals no-op and no credentials appear in source, logs, or committed env files.\n5. Run the `archipy-reviewer` subagent on the changes and fix every **Must fix** finding it reports.\n6. Report extras, config keys, bootstrap changes, and commands run.\n\n## Docs\n\n- https:\u002F\u002Fsyntaxarc.github.io\u002FArchiPy\u002Ftutorials\u002Fobservability\u002F\n- https:\u002F\u002Fsyntaxarc.github.io\u002FArchiPy\u002Ftutorials\u002Fhelpers\u002Finterceptors\u002F\n",{"name":5,"description":7},"main","60b791bf9902a80e9a0bbac9d7cf04ea5c559af0","skills\u002Fscaffold-observability",1,"https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin","https:\u002F\u002Fsyntaxarc.github.io\u002FArchiPy\u002F","https:\u002F\u002Fgithub.com\u002FSyntaxArc","A structured, modern approach to development.","2026-11-07 21:30:40",{"source":8,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add SyntaxArc\u002Farchipy-plugin --skill scaffold-observability",{"tool":38,"command":39},"bunx","bunx skills add SyntaxArc\u002Farchipy-plugin --skill scaffold-observability",{"tool":41,"command":42},"pnpm","pnpm dlx skills add SyntaxArc\u002Farchipy-plugin --skill scaffold-observability","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-observability\u002FSKILL.md",true,[],[47,54,61,68,75,82],{"skillNo":48,"name":49,"nameZh":6,"description":50,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":51,"categories":52,"keywords":53,"publishedAt":18},"01M79GRZRMZGQ4N8DZY0JQ1TYC","scaffold-utils","Add or wire pure helpers\u002Futils, preferring ArchiPy utils (datetime, JWT, password, file, string). Use for \"add a helper\u002Futil function\", \"format dates\", \"hash passwords\", or \"generate tokens\".","https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-utils\u002FSKILL.md",[],[],{"skillNo":55,"name":56,"nameZh":6,"description":57,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":60,"publishedAt":18},"01M79GRWMT4CC0MEQNWPJF3MA3","scaffold-service","Scaffold a thin FastAPI router or gRPC servicer under services\u002F{domain}\u002Fv{n}\u002F with AppUtils bootstrap. Use for \"add an endpoint\u002Froute\u002FAPI\", \"expose via REST\u002FgRPC\", or \"new API version\".","https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-service\u002FSKILL.md",[],[],{"skillNo":62,"name":63,"nameZh":6,"description":64,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":65,"categories":66,"keywords":67,"publishedAt":18},"01M79GRPK6B0S157614VXJCW5Y","scaffold-models","Scaffold ArchiPy models under models\u002F: domain\u002Frepository DTOs, errors, optional entities and types. Use for \"add DTO\u002Fschema\u002Frequest\u002Fresponse model\", \"new error type\", or \"SQLAlchemy entity\".","https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-models\u002FSKILL.md",[],[],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":18},"01M79GRK8F6RZPX6V4EA24379G","scaffold-logic","Scaffold an ArchiPy logic (use case) under logics\u002F{domain}\u002F with a unit-of-work decorator and DTO I\u002FO. Use for \"add business logic\", \"new use case\", \"transactional operation\", or \"service layer method\".","https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-logic\u002FSKILL.md",[],[],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":18},"01M79GRF6HFDN1RZMPZJM54TGR","scaffold-interceptor","Add or wire cross-cutting FastAPI\u002FgRPC interceptors or middleware, preferring ArchiPy's. Use for \"add middleware\", \"request ID\u002Flogging\u002Fauth interceptor\", or \"gRPC interceptor\".","https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-interceptor\u002FSKILL.md",[],[],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":18},"01M79GRAZBDYDTX9JMBX171KEK","scaffold-health-checks","Scaffold FastAPI\u002FgRPC liveness, readiness, and startup health checks, graceful shutdown, and optional Kubernetes probes. Use for \"health endpoint\", \"readiness\u002Fliveness probe\", or \"k8s probes\".","https:\u002F\u002Fgithub.com\u002FSyntaxArc\u002Farchipy-plugin\u002Fblob\u002Fmain\u002Fskills\u002Fscaffold-health-checks\u002FSKILL.md",[],[]]