{"id":16931856,"url":"https://github.com/leodido/caddy-jsonselect-encoder","last_synced_at":"2025-04-11T18:33:39.722Z","repository":{"id":38440035,"uuid":"386604752","full_name":"leodido/caddy-jsonselect-encoder","owner":"leodido","description":"Pick what to log in JSON format","archived":false,"fork":false,"pushed_at":"2022-06-03T22:17:37.000Z","size":147,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T14:38:58.177Z","etag":null,"topics":["caddy","encoder","format","formatter","json","logging","output","parse","select"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leodido.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-16T10:54:55.000Z","updated_at":"2023-11-22T20:45:36.000Z","dependencies_parsed_at":"2022-08-18T11:32:45.258Z","dependency_job_id":null,"html_url":"https://github.com/leodido/caddy-jsonselect-encoder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leodido%2Fcaddy-jsonselect-encoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leodido%2Fcaddy-jsonselect-encoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leodido%2Fcaddy-jsonselect-encoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leodido%2Fcaddy-jsonselect-encoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leodido","download_url":"https://codeload.github.com/leodido/caddy-jsonselect-encoder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248459072,"owners_count":21107218,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caddy","encoder","format","formatter","json","logging","output","parse","select"],"created_at":"2024-10-13T20:44:52.080Z","updated_at":"2025-04-11T18:33:39.699Z","avatar_url":"https://github.com/leodido.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# caddy-jsonselect-encoder\n\n\u003e Select what you want to log\n\nBy using a selector you can choose what (and how) you want to emit your JSON logs.\n\n## Module\n\nThe **module name** is `jsonselect`.\n\nIts syntax is:\n\n```caddyfile\njsonselect \u003cselector\u003e {\n    message_key \u003ckey\u003e\n    level_key   \u003ckey\u003e\n    time_key    \u003ckey\u003e\n    name_key    \u003ckey\u003e\n    caller_key  \u003ckey\u003e\n    stacktrace_key \u003ckey\u003e\n    line_ending  \u003cchar\u003e\n    time_format  \u003cformat\u003e\n    level_format \u003cformat\u003e\n}\n```\n\n### Selector\n\nA selector represents the JSON path of the log entry you want to select.\n\nThe syntax is heavily inspired by [buger/jsonparser](https://github.com/buger/jsonparser). With some additions...\n\nSo, you can write a selector like the following one to only output the HTTP status code and the logger name:\n\n```caddyfile\n{status} {logger}\n```\n\nOr you can even select deeper in the JSON log entry:\n\n```caddyfile\n{request\u003ehost} {request\u003emethod}\n```\n\nThe resulting JSON will respect the hierarchy of the selector paths.\n\nThus, for a selector like `{request\u003emethod}` the resulting JSON log entry will look like this:\n\n```json\n{\"request\":{\"method\":\"GET\"}}\n```\n\nNotice that the parsing of selectors happens at provisioning time to do not impact encoding performances.\n\nFinally, I extended the syntax to support the reshaping of the resulting JSON keys.\n\nTo define a key for a given selector, you can use the following syntax:\n\n```caddyfile\n{key:selector}\n```\n\nFor example, to store the status of a log entry in a `httpRequest.responseStatus` JSON path you can write:\n\n```caddyfile\n{httpResponse\u003eresponseStatus:status}\n```\n\nWhich will output the following JSON:\n\n```json\n{\"httpRequest\":{\"responseStatus\":404}}\n```\n\nThis is particularly useful to adapt your log entries to different JSON structures like the Stackdriver one.\n\n## Caddyfile\n\nLog a JSON containing only the level, the timestamp, and the message of the log entry.\nAlso, use \"mex\" as a key for the message.\n\n```console\nlog {\n  output stdout\n  format jsonselect \"{level} {ts} {mex}\" {\n    message_key mex\n  }\n}\n```\n\nThis will output:\n\n```json\n{\"level\":\"info\",\"ts\":1626453781.3333929,\"mex\":\"handled request\"}\n```\n\nLog the host of the request and the duration:\n\n```caddyfile\nlog {\n  output stdout\n  format jsonselect \"{request\u003ehost} {duration}\"\n}\n```\n\nWhich outputs something like the following JSON respecting the selector's path structure:\n\n```json\n{\"request\":{\"host\":\"localhost:2015\"},\"duration\":0.003321}\n```\n\nMaybe you wanna log for Stackdriver ...\n\n```caddyfile\nlog {\n  format jsonselect \"{severity} {timestamp} {logName}\" {\n    level_key \"severity\"\n    level_format \"upper\"\n    time_key \"timestamp\"\n    time_format \"rfc3339\"\n    name_key \"logName\"\n  }\n}\n```\n\nThis outputs:\n\n```json\n{\"severity\":\"ERROR\",\"timestamp\":\"2021-07-16T12:55:10Z\",\"logName\":\"http.log.access.log0\"}\n```\n\nEven more, you can define keys for the resulting output to better match the [Stackdriver log entry format](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry).\n\nLike this:\n\n```caddyfile\nlog {\n  format jsonselect \"{severity:level} {timestamp:ts} {httpRequest\u003erequestMethod:request\u003emethod} {httpRequest\u003eprotocol:request\u003eproto} {httpRequest\u003estatus:status} {httpRequest\u003eresponseSize:size} {httpRequest\u003euserAgent:request\u003eheaders\u003eUser-Agent\u003e[0]}\" {\n    time_format \"rfc3339_nano\"\n    level_format \"upper\"\n  }\n}\n```\n\nWhich outputs:\n\n```json\n{\"severity\":\"INFO\",\"timestamp\":\"2021-07-19T14:48:56.262966Z\",\"httpRequest\":{\"protocol\":\"HTTP/2.0\",\"requestMethod\":\"GET\",\"responseSize\":17604,\"status\":200,\"userAgent\":\"Mozilla/5.0 ...\"}}\n```\n\n## Try it out\n\nFrom the root directoy of this project, run:\n\n```console\nxcaddy run\n```\n\nThen open \u003chttps://localhost:2015\u003e, go on existing and non-existing pages, and observe the access logs.\n\nTo install xcaddy in case you need to, run:\n\n```console\ngo get -u github.com/caddyserver/xcaddy/cmd/xcaddy\n```\n\n## Build\n\nTo build [Caddy](https://github.com/caddyserver/caddy) with this module in, execute:\n\n```console\nxcaddy build --with github.com/leodido/caddy-jsonselect-encoder\n```\n\n---\n\n[![Analytics](https://ga-beacon.appspot.com/UA-49657176-1/caddy-jsonselect-encoder?flat)](https://github.com/igrigorik/ga-beacon)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleodido%2Fcaddy-jsonselect-encoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleodido%2Fcaddy-jsonselect-encoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleodido%2Fcaddy-jsonselect-encoder/lists"}