{"id":34212723,"url":"https://github.com/mantzas/patron","last_synced_at":"2026-03-10T16:03:52.792Z","repository":{"id":57498451,"uuid":"125984252","full_name":"mantzas/patron","owner":"mantzas","description":"Go microservice framework","archived":false,"fork":false,"pushed_at":"2024-09-18T17:00:38.000Z","size":6214,"stargazers_count":41,"open_issues_count":0,"forks_count":65,"subscribers_count":5,"default_branch":"master","last_synced_at":"2026-03-01T16:57:04.406Z","etag":null,"topics":["framework","go","golang","microservice","microservices"],"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/mantzas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-20T08:24:35.000Z","updated_at":"2025-07-18T22:15:19.000Z","dependencies_parsed_at":"2024-06-18T22:49:56.861Z","dependency_job_id":"dda25694-dd68-4b33-a13a-a44a43b3326d","html_url":"https://github.com/mantzas/patron","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/mantzas/patron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mantzas%2Fpatron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mantzas%2Fpatron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mantzas%2Fpatron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mantzas%2Fpatron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mantzas","download_url":"https://codeload.github.com/mantzas/patron/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mantzas%2Fpatron/sbom","scorecard":{"id":615778,"data":{"date":"2025-08-11","repo":{"name":"github.com/mantzas/patron","commit":"5834954b673d7896dfde2f1a101ba3dc86d68289"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":1,"reason":"Found 2/18 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2021-0053 / GHSA-c3h9-896r-86jm","Warn: Project is vulnerable to: GO-2022-0322 / GHSA-cg3q-j54f-5p7p"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 29 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T03:53:22.706Z","repository_id":57498451,"created_at":"2025-08-21T03:53:22.706Z","updated_at":"2025-08-21T03:53:22.706Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30341667,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T15:55:29.454Z","status":"ssl_error","status_checked_at":"2026-03-10T15:54:58.440Z","response_time":106,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["framework","go","golang","microservice","microservices"],"created_at":"2025-12-15T21:27:41.802Z","updated_at":"2026-03-10T16:03:52.778Z","avatar_url":"https://github.com/mantzas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# patron [![CircleCI](https://circleci.com/gh/mantzas/patron.svg?style=svg)](https://circleci.com/gh/mantzas/patron) [![codecov](https://codecov.io/gh/mantzas/patron/branch/master/graph/badge.svg)](https://codecov.io/gh/mantzas/patron) [![Go Report Card](https://goreportcard.com/badge/github.com/mantzas/patron)](https://goreportcard.com/report/github.com/mantzas/patron) [![GoDoc](https://godoc.org/github.com/mantzas/patron?status.svg)](https://godoc.org/github.com/mantzas/patron)\n\nPatron is a framework for creating microservices, originally created by Sotiris Mantzaris (https://github.com/mantzas). This fork is maintained by Beat Engineering (https://thebeat.co)\n\n`Patron` is french for `template` or `pattern`, but it means also `boss` which we found out later (no pun intended).\n\nThe entry point of the framework is the `Service`. The `Service` uses `Components` to handle the processing of sync and async requests. The `Service` starts by default a `HTTP Component` which hosts the debug, health and metric endpoints. Any other endpoints will be added to the default `HTTP Component` as `Routes`. The service set's up by default logging with `zerolog`, tracing and metrics with `jaeger` and `prometheus`.\n\n`Patron` provides abstractions for the following functionality of the framework:\n\n- service, which orchestrates everything\n- components and processors, which provide a abstraction of adding processing functionality to the service\n  - asynchronous message processing (RabbitMQ, Kafka)\n  - synchronous processing (HTTP)\n- metrics and tracing\n- logging\n\n`Patron` provides same defaults for making the usage as simple as possible.\n\n## How to Contribute\n\nPlease see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## patron-cli\n\nThe framework supplies a cli in order to simplify repository generation with the following features:\n\n- git repository creation\n- cmd folder and main.go creation with build version support (`go build -ldflags '-X main.version=1.0.0' main.go`)\n- go module support and vendoring\n- Dockerfile with version support (`docker build --build-arg version=1.0.0`)\n\nThe latest version can be installed with\n\n```go\ngo get github.com/mantzas/patron/cmd/patron\n```\n\nThe below is an example of a service created with the cli that has a module name `github.com/mantzas/test` and will be created in the test folder in the current directory.\n\n```go\npatron -m \"github.com/mantzas/test\" -p \"test\"\n```\n\n## Service\n\nThe `Service` has the role of glueing all of the above together, which are:\n\n- setting up logging\n- setting up default HTTP component with the following endpoints configured:\n  - profiling via pprof\n  - health check\n  - info endpoint for returning information about the service\n- setting up termination by os signal\n- starting and stopping components\n- handling component errors\n- setting up metrics and tracing\n\nThe service has some default settings which can be changed via environment variables:\n\n- Service HTTP port, for setting the default HTTP components port to `50000` with `PATRON_HTTP_DEFAULT_PORT`\n- Log level, for setting zerolog with `INFO` log level with `PATRON_LOG_LEVEL`\n- Tracing, for setting up jaeger tracing with\n  - agent address `0.0.0.0:6831` with `PATRON_JAEGER_AGENT`\n  - sampler type `probabilistic`with `PATRON_JAEGER_SAMPLER_TYPE`\n  - sampler param `0.1` with `PATRON_JAEGER_SAMPLER_PARAM`\n\n### Component\n\nA `Component` is a interface that exposes the following API:\n\n```go\ntype Component interface {\n  Run(ctx context.Context) error  \n  Info() map[string]interface{}\n}\n```\n\nThe above API gives the `Service` the ability to start and gracefully shutdown a `component` via context cancellation. Furthermore the component describes itself by implementing the `Info` method and thus giving the service the ability to report the information of all components. The framework divides the components in 2 categories:\n\n- synchronous, which are components that follow the request/response pattern and\n- asynchronous, which consume messages from a source but don't respond anything back\n\nThe following component implementations are available:\n\n- HTTP (sync)\n- RabbitMQ consumer (async)\n- Kafka consumer (async)\n\nAdding to the above list is as easy as implementing a `Component` and a `Processor` for that component.\n\n## Example\n\nSetting up a new service with a HTTP `Component` is as easy as the following code:\n\n```go\n  // Set up HTTP routes\n  routes := make([]sync_http.Route, 0)\n  routes = append(routes, sync_http.NewRoute(\"/\", http.MethodGet, processor, true))\n  \n  srv, err := patron.New(\"test\", patron.Routes(routes))\n  if err != nil {\n    log.Fatalf(\"failed to create service %v\", err)\n  }\n\n  err = srv.Run()\n  if err != nil {\n    log.Fatalf(\"failed to create service %v\", err)\n  }\n```\n\nThe above is pretty much self-explanatory. The processor follows the sync pattern.\n\n## Processors\n\n### Synchronous\n\nThe implementation of the processor is responsible to create a `Request` by providing everything that is needed (Headers, Fields, decoder, raw io.Reader) pass it to the implementation by invoking the `Process` method and handle the `Response` or the `error` returned by the processor.\n\nThe sync package contains only a function definition along with the models needed:\n\n```go\ntype ProcessorFunc func(context.Context, *Request) (*Response, error)\n```\n\nThe `Request` model contains the following properties (which are provided when calling the \"constructor\" `NewRequest`)\n\n- Fields, which may contain any fields associated with the request\n- Raw, the raw request data (if any) in the form of a `io.Reader`\n- Headers, the request headers in the form of `map[string]string`\n- decode, which is a function of type `encoding.Decode` that decodes the raw reader\n\nA exported function exists for decoding the raw io.Reader in the form of\n\n```go\nDecode(v interface{}) error\n```\n\nThe `Response` model contains the following properties (which are provided when calling the \"constructor\" `NewResponse`)\n\n- Payload, which may hold a struct of type `interface{}`\n\n### Asynchronous\n\nThe implementation of the async processor follows exactly the same principle as the sync processor.\nThe main difference is that:\n\n- The `Request` is the `Message` and contains only data as `[]byte`\n- There is no `Response`, so the processor may return a error\n\n```go\ntype ProcessorFunc func(context.Context, *Message) error\n```\n\nEverything else is exactly the same.\n\n## Metrics and Tracing\n\nTracing and metrics are provided by Jaeger's implementation of the OpenTracing project.\nEvery component has been integrated with the above library and produces traces and metrics.\nMetrics are provided with the default HTTP component at the `/metrics` route for Prometheus to scrape.\nTracing will be send to a jaeger agent which can be setup though environment variables mentioned in the config section. Sane defaults are applied for making the use easy.\nWe have included some clients inside the trace package which are instrumented and allow propagation of tracing to\ndownstream systems. The tracing information is added to each implementations header. These clients are:\n\n- HTTP\n- AMQP\n- Kafka\n- SQL\n\n## Reliability\n\nThe reliability package contains the following implementations:\n\n- Circuit Breaker\n\n### Circuit Breaker\n\nThe circuit breaker supports a half-open state which allows to probe for successful responses in order to close the circuit again. Every aspect of the circuit breaker is configurable via it's settings.\n\n## Clients\n\nThe following clients have been implemented:\n\n- http, with distributed tracing and optional circuit breaker\n- sql, with distributed tracing\n- kafka, with distributed tracing\n- amqp, with distributed tracing\n\n## Logging\n\nThe log package is designed to be a leveled logger with field support.\n\nThe log package defines the logger interface and a factory function type that needs to be implemented in order to set up the logging in this framework.\n\n```go\n  // instantiate the implemented factory func type and fields (map[string]interface{})\n  err := log.Setup(factory, fields)\n  // handle error\n```\n\n`If the setup is omitted the package will not setup any logging!`\n\nFrom there logging is as simple as\n\n```go\n  log.Info(\"Hello world!\")\n```\n\nThe implementations should support following log levels:\n\n- Debug, which should log the message with debug level\n- Info, which should log the message with info level\n- Warn, which should log the message with warn level\n- Error, which should log the message with error level\n- Panic, which should log the message with panic level and panics\n- Fatal, which should log the message with fatal level and terminates the application\n\nThe first four (Debug, Info, Warn and Error) give the opportunity to differentiate the messages by severity. The last two (Panic and Fatal) do the same and do additional actions (panic and termination).\n\nThe package supports fields, which are logged along with the message, to augment the information further to ease querying in the log management system.\n\nThe following implementations are provided as sub-package and are by default wired up in the framework:\n\n- zerolog, which supports the excellent [zerolog](https://github.com/rs/zerolog) library and is set up by default\n\n### Context Logging\n\nLogs can be associated with some contextual data e.g. a request id. Every line logged should contain this id thus grouping the logs together. This is achieved with the usage of the context package like demonstrated bellow:\n\n```go\nctx := log.WithContext(r.Context(), log.Sub(map[string]interface{}{\"requestID\": uuid.New().String()}))\n```\n\nThe context travels through the code as a argument and can be acquired as follows:\n\n```go\nlogger:=log.FromContext(ctx)\nlogger.Infof(\"request processed\")\n```\n\nBenchmarks are provided to show the performance of this.\n\n`Every provided component creates a context logger which is then propagated in the context`\n\n### Logger\n\nThe logger interface defines the actual logger.\n\n```go\ntype Logger interface {\n  Fatal(...interface{})\n  Fatalf(string, ...interface{})\n  Panic(...interface{})\n  Panicf(string, ...interface{})\n  Error(...interface{})\n  Errorf(string, ...interface{})\n  Warn(...interface{})\n  Warnf(string, ...interface{})\n  Info(...interface{})\n  Infof(string, ...interface{})\n  Debug(...interface{})\n  Debugf(string, ...interface{})\n}\n```\n\nIn order to be consistent with the design the implementation of the `Fatal(f)` have to terminate the application with an error and the `Panic(f)` need to panic.\n\n### Factory\n\nThe factory function type defines a factory for creating a logger.\n\n```go\ntype FactoryFunc func(map[string]interface{}) Logger\n```\n\n## Security\n\nThe necessary abstraction are available to implement authentication in the following components:\n\n- HTTP\n\n### HTTP\n\nIn order to use authentication, a authenticator has to be implement following the interface:\n\n```go\ntype Authenticator interface {\n  Authenticate(req *http.Request) (bool, error)\n}\n```\n\nThis authenticator can then be used to set up routes with authentication.\n\nThe following authenticator are available:\n\n- API key authenticator, see examples\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmantzas%2Fpatron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmantzas%2Fpatron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmantzas%2Fpatron/lists"}