{"id":13413338,"url":"https://github.com/yuseferi/zax","last_synced_at":"2026-01-24T15:37:04.739Z","repository":{"id":173679472,"uuid":"651079785","full_name":"yuseferi/zax","owner":"yuseferi","description":"Golang Zap logger with context","archived":false,"fork":false,"pushed_at":"2025-12-25T22:32:10.000Z","size":62,"stargazers_count":32,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-27T08:56:56.414Z","etag":null,"topics":["go","golang","golang-logger-with-context","zap","zap-with-context"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yuseferi.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":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-06-08T12:55:17.000Z","updated_at":"2025-12-25T22:28:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"d83d5026-3cb2-4cac-80f6-90aad183a845","html_url":"https://github.com/yuseferi/zax","commit_stats":null,"previous_names":["yuseferi/zax"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/yuseferi/zax","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuseferi%2Fzax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuseferi%2Fzax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuseferi%2Fzax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuseferi%2Fzax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuseferi","download_url":"https://codeload.github.com/yuseferi/zax/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuseferi%2Fzax/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28730323,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["go","golang","golang-logger-with-context","zap","zap-with-context"],"created_at":"2024-07-30T20:01:38.122Z","updated_at":"2026-01-24T15:37:04.733Z","avatar_url":"https://github.com/yuseferi.png","language":"Go","funding_links":[],"categories":["Logging","日志记录"],"sub_categories":["Search and Analytic Databases","检索及分析资料库"],"readme":"\u003cdiv align=\"center\"\u003e\n\n# ⚡ Zax\n\n### Context-Aware Logging for Go with Uber's Zap\n\n[![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.21-00ADD8?style=flat-square\u0026logo=go)](https://go.dev/)\n[![Go Reference](https://pkg.go.dev/badge/github.com/yuseferi/zax/v2.svg)](https://pkg.go.dev/github.com/yuseferi/zax/v2)\n[![codecov](https://img.shields.io/codecov/c/github/yuseferi/zax?style=flat-square\u0026logo=codecov)](https://codecov.io/github/yuseferi/zax)\n[![Go Report Card](https://goreportcard.com/badge/github.com/yuseferi/zax?style=flat-square)](https://goreportcard.com/report/github.com/yuseferi/zax)\n[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg?style=flat-square)](https://www.gnu.org/licenses/agpl-3.0)\n[![GitHub release](https://img.shields.io/github/v/release/yuseferi/zax?style=flat-square\u0026logo=github)](https://github.com/yuseferi/zax/releases)\n\n[![CodeQL](https://github.com/yuseferi/zax/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/yuseferi/zax/actions/workflows/github-code-scanning/codeql)\n[![Check \u0026 Build](https://github.com/yuseferi/zax/actions/workflows/ci.yml/badge.svg)](https://github.com/yuseferi/zax/actions/workflows/ci.yml)\n\n\u003cbr /\u003e\n\n**Zax** seamlessly integrates [Zap Logger](https://github.com/uber-go/zap) with Go's `context.Context`, enabling you to carry structured logging fields across your entire request lifecycle without boilerplate.\n\n[Features](#-features) •\n[Installation](#-installation) •\n[Quick Start](#-quick-start) •\n[API Reference](#-api-reference) •\n[Benchmarks](#-benchmarks) •\n[Contributing](#-contributing)\n\n\u003c/div\u003e\n\n---\n\n## 🎯 Why Zax?\n\nIn modern Go applications, especially microservices, you often need to:\n\n- 🔍 **Trace requests** across multiple functions and services\n- 📊 **Correlate logs** with trace IDs, span IDs, and user context\n- 🧹 **Avoid boilerplate** by not passing loggers as function parameters\n- ⚡ **Maintain performance** without sacrificing structured logging\n\nZax solves these problems elegantly by storing Zap fields in context, making them available wherever you need to log.\n\n## ✨ Features\n\n| Feature | Description |\n|---------|-------------|\n| 🚀 **Zero Dependencies** | Only requires `go.uber.org/zap` |\n| 🎯 **Context-Native** | Works seamlessly with Go's `context.Context` |\n| ⚡ **High Performance** | Minimal overhead (~20ns per operation) |\n| 🔧 **Simple API** | Just 5 functions to learn |\n| 🍬 **SugaredLogger Support** | Works with both `*zap.Logger` and `*zap.SugaredLogger` |\n| 🧪 **Well Tested** | Comprehensive test coverage |\n\n## 📦 Installation\n\n```bash\ngo get -u github.com/yuseferi/zax/v2\n```\n\n**Requirements:** Go 1.21 or higher\n\n## 🚀 Quick Start\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \n    \"github.com/yuseferi/zax/v2\"\n    \"go.uber.org/zap\"\n)\n\nfunc main() {\n    logger, _ := zap.NewProduction()\n    defer logger.Sync()\n    \n    ctx := context.Background()\n    \n    // Add trace_id to context\n    ctx = zax.Set(ctx, []zap.Field{\n        zap.String(\"trace_id\", \"abc-123\"),\n        zap.String(\"user_id\", \"user-456\"),\n    })\n    \n    // Log with context fields - automatically includes trace_id and user_id\n    logger.With(zax.Get(ctx)...).Info(\"request started\")\n    \n    // Pass context to other functions\n    processRequest(ctx, logger)\n}\n\nfunc processRequest(ctx context.Context, logger *zap.Logger) {\n    // All logs automatically include trace_id and user_id!\n    logger.With(zax.Get(ctx)...).Info(\"processing request\")\n    \n    // Append additional fields without losing existing ones\n    ctx = zax.Append(ctx, []zap.Field{\n        zap.String(\"step\", \"validation\"),\n    })\n    \n    logger.With(zax.Get(ctx)...).Info(\"validation complete\")\n}\n```\n\n**Output:**\n```json\n{\"level\":\"info\",\"msg\":\"request started\",\"trace_id\":\"abc-123\",\"user_id\":\"user-456\"}\n{\"level\":\"info\",\"msg\":\"processing request\",\"trace_id\":\"abc-123\",\"user_id\":\"user-456\"}\n{\"level\":\"info\",\"msg\":\"validation complete\",\"trace_id\":\"abc-123\",\"user_id\":\"user-456\",\"step\":\"validation\"}\n```\n\n## 📖 API Reference\n\n### Core Functions\n\n#### `Set(ctx, fields) context.Context`\nStores zap fields in context. **Replaces** any existing fields.\n\n```go\nctx = zax.Set(ctx, []zap.Field{\n    zap.String(\"trace_id\", \"my-trace-id\"),\n    zap.Int(\"request_num\", 42),\n})\n```\n\n#### `Append(ctx, fields) context.Context`\nAppends fields to existing context fields. **Preserves** previously set fields.\n\n```go\n// Existing: trace_id\nctx = zax.Append(ctx, []zap.Field{\n    zap.String(\"span_id\", \"my-span-id\"),\n})\n// Now has: trace_id + span_id\n```\n\n#### `Get(ctx) []zap.Field`\nRetrieves all stored fields from context.\n\n```go\nfields := zax.Get(ctx)\nlogger.With(fields...).Info(\"message\")\n```\n\n#### `GetField(ctx, key) zap.Field`\nRetrieves a specific field by key.\n\n```go\ntraceField := zax.GetField(ctx, \"trace_id\")\nfmt.Println(traceField.String) // \"my-trace-id\"\n```\n\n#### `GetSugared(ctx) []interface{}`\nReturns fields as key-value pairs for `SugaredLogger`.\n\n```go\nsugar := logger.Sugar()\nsugar.With(zax.GetSugared(ctx)...).Info(\"sugared log\")\n```\n\n## 🔥 Real-World Example\n\n### HTTP Middleware with Distributed Tracing\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"net/http\"\n    \n    \"github.com/yuseferi/zax/v2\"\n    \"go.uber.org/zap\"\n)\n\ntype Server struct {\n    logger *zap.Logger\n}\n\n// Middleware injects trace context into all requests\nfunc (s *Server) TracingMiddleware(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        ctx := r.Context()\n        \n        // Extract or generate trace ID\n        traceID := r.Header.Get(\"X-Trace-ID\")\n        if traceID == \"\" {\n            traceID = generateTraceID()\n        }\n        \n        // Store in context\n        ctx = zax.Set(ctx, []zap.Field{\n            zap.String(\"trace_id\", traceID),\n            zap.String(\"method\", r.Method),\n            zap.String(\"path\", r.URL.Path),\n        })\n        \n        s.logger.With(zax.Get(ctx)...).Info(\"request received\")\n        \n        next.ServeHTTP(w, r.WithContext(ctx))\n    })\n}\n\n// Handler automatically has access to trace context\nfunc (s *Server) HandleUser(w http.ResponseWriter, r *http.Request) {\n    ctx := r.Context()\n    \n    // Add handler-specific context\n    ctx = zax.Append(ctx, []zap.Field{\n        zap.String(\"handler\", \"user\"),\n    })\n    \n    user, err := s.fetchUser(ctx)\n    if err != nil {\n        s.logger.With(zax.Get(ctx)...).Error(\"failed to fetch user\", zap.Error(err))\n        http.Error(w, \"Internal Error\", 500)\n        return\n    }\n    \n    s.logger.With(zax.Get(ctx)...).Info(\"user fetched successfully\",\n        zap.String(\"user_id\", user.ID),\n    )\n}\n\nfunc (s *Server) fetchUser(ctx context.Context) (*User, error) {\n    // All logs here include trace_id, method, path, and handler!\n    s.logger.With(zax.Get(ctx)...).Debug(\"querying database\")\n    // ... database logic\n    return \u0026User{}, nil\n}\n```\n\n## 📊 Benchmarks\n\nZax V2 is optimized for performance. Here's how it compares:\n\n| Benchmark | ns/op | B/op | allocs/op |\n|-----------|-------|------|-----------|\n| **Pure Zap** | ~35 | 112 | 1 |\n| **Zax V2** | ~57 | 72 | 2 |\n| Zax V1 | ~65 | 160 | 2 |\n\n\u003e 💡 **V2 uses 55% less memory** than V1 by storing only fields instead of the entire logger object.\n\n\u003cdetails\u003e\n\u003csummary\u003e📋 Full Benchmark Results\u003c/summary\u003e\n\n```\npkg: github.com/yuseferi/zax/v2\nBenchmarkLoggingWithOnlyZap-10          103801226               35.56 ns/op          112 B/op          1 allocs/op\nBenchmarkLoggingWithOnlyZap-10          98576570                35.56 ns/op          112 B/op          1 allocs/op\nBenchmarkLoggingWithOnlyZap-10          100000000               35.24 ns/op          112 B/op          1 allocs/op\nBenchmarkLoggingWithOnlyZap-10          100000000               34.85 ns/op          112 B/op          1 allocs/op\nBenchmarkLoggingWithOnlyZap-10          100000000               34.98 ns/op          112 B/op          1 allocs/op\nBenchmarkLoggingWithZaxV2-10            64324434                56.02 ns/op           72 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV2-10            63939517                56.98 ns/op           72 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV2-10            63374052                57.60 ns/op           72 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV2-10            63417358                57.37 ns/op           72 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV2-10            57964246                57.97 ns/op           72 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV1-10            54062712                66.40 ns/op          160 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV1-10            53155524                65.61 ns/op          160 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV1-10            54428521                64.19 ns/op          160 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV1-10            55420744                64.28 ns/op          160 B/op          2 allocs/op\nBenchmarkLoggingWithZaxV1-10            55199061                64.50 ns/op          160 B/op          2 allocs/op\nPASS\nok      github.com/yuseferi/zax/v2      56.919s\n```\n\n\u003c/details\u003e\n\n## 🤝 Contributing\n\nWe ❤️ contributions! Here's how you can help:\n\n1. 🍴 **Fork** the repository\n2. 🌿 **Create** a feature branch (`git checkout -b feature/amazing-feature`)\n3. 💻 **Commit** your changes (`git commit -m 'Add amazing feature'`)\n4. 📤 **Push** to the branch (`git push origin feature/amazing-feature`)\n5. 🎉 **Open** a Pull Request\n\n### Development\n\n```bash\n# Clone the repository\ngit clone https://github.com/yuseferi/zax.git\ncd zax\n\n# Run tests\ngo test -v ./...\n\n# Run benchmarks\ngo test -bench=. -benchmem\n\n# Run linter\ngolangci-lint run\n```\n\n## 📄 License\n\nThis project is licensed under the **GNU Affero General Public License v3.0** - see the [LICENSE](LICENSE) file for details.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**Made with ❤️ by [Yusef Mohamadi](https://github.com/yuseferi) and contributors**\n\n⭐ **Star this repo** if you find it useful!\n\n[Report Bug](https://github.com/yuseferi/zax/issues) •\n[Request Feature](https://github.com/yuseferi/zax/issues)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuseferi%2Fzax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuseferi%2Fzax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuseferi%2Fzax/lists"}