{"id":41784216,"url":"https://github.com/mwat56/apachelogger","last_synced_at":"2026-01-25T04:08:11.146Z","repository":{"id":57491097,"uuid":"184599145","full_name":"mwat56/apachelogger","owner":"mwat56","description":"An Apache style file logger for the Go web-server","archived":false,"fork":false,"pushed_at":"2025-05-04T13:12:27.000Z","size":130,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-04T14:22:28.107Z","etag":null,"topics":["apache","go","golang","golang-package","logfile","logging-library","middleware","web-site"],"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/mwat56.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-05-02T14:49:12.000Z","updated_at":"2025-05-04T13:12:30.000Z","dependencies_parsed_at":"2025-05-04T14:21:23.156Z","dependency_job_id":null,"html_url":"https://github.com/mwat56/apachelogger","commit_stats":null,"previous_names":["mwat56/go-apachelogger"],"tags_count":37,"template":false,"template_full_name":null,"purl":"pkg:github/mwat56/apachelogger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwat56%2Fapachelogger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwat56%2Fapachelogger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwat56%2Fapachelogger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwat56%2Fapachelogger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mwat56","download_url":"https://codeload.github.com/mwat56/apachelogger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwat56%2Fapachelogger/sbom","scorecard":{"id":669762,"data":{"date":"2025-08-11","repo":{"name":"github.com/mwat56/apachelogger","commit":"6b74059a25f75ff8e80ceab8305d1803dd1347b7"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","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":"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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"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":"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":"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":"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":"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.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":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"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":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T19:33:36.864Z","repository_id":57491097,"created_at":"2025-08-21T19:33:36.864Z","updated_at":"2025-08-21T19:33:36.864Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28742983,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T02:46:29.005Z","status":"ssl_error","status_checked_at":"2026-01-25T02:44:29.968Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["apache","go","golang","golang-package","logfile","logging-library","middleware","web-site"],"created_at":"2026-01-25T04:08:10.667Z","updated_at":"2026-01-25T04:08:11.138Z","avatar_url":"https://github.com/mwat56.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ApacheLogger\n\n[![Golang](https://img.shields.io/badge/Language-Go-green.svg)](https://golang.org/)\n[![GoDoc](https://godoc.org/github.com/mwat56/apachelogger?status.svg)](https://godoc.org/github.com/mwat56/apachelogger/)\n[![Go Report](https://goreportcard.com/badge/github.com/mwat56/apachelogger)](https://goreportcard.com/report/github.com/mwat56/apachelogger)\n[![Issues](https://img.shields.io/github/issues/mwat56/apachelogger.svg)](https://github.com/mwat56/apachelogger/issues?q=is%3Aopen+is%3Aissue)\n[![Size](https://img.shields.io/github/repo-size/mwat56/apachelogger.svg)](https://github.com/mwat56/apachelogger/)\n[![Tag](https://img.shields.io/github/tag/mwat56/apachelogger.svg)](https://github.com/mwat56/apachelogger/tags)\n[![License](https://img.shields.io/github/license/mwat56/apachelogger.svg)](https://github.com/mwat56/apachelogger/blob/main/LICENSE)\n[![View examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg)](https://github.com/mwat56/apachelogger/blob/main/cmd/demo.go)\n\n- [ApacheLogger](#apachelogger)\n\t- [Purpose](#purpose)\n\t- [Installation](#installation)\n\t- [Usage](#usage)\n\t- [Special Features](#special-features)\n\t- [Libraries](#libraries)\n\t- [Licence](#licence)\n\n----\n\n## Purpose\n\n`ApacheLogger` is a `Go` middleware package that adds Apache-style logging to `Go` web servers. Key features include:\n\n- Logs HTTP requests in Apache-compatible format,\n- provides privacy protection by anonymizing IP addresses,\n- supports both access and error logging,\n- offers manual logging functions (`Log()` and `Err()`),\n- catches and recovers from panics, logging them to the error log,\n- simple integration via a `Wrap()` function that wraps your HTTP handler.\n\nThe package is designed to be lightweight with no external dependencies, making it easy to add professional logging to any Go web application while maintaining privacy compliance.\n\nThis package can be used to add a logfile facility to your `Go` web-server.\nThe format of the generated logfile entries resembles that of the popular _Apache_ web-server (see below).\n\n## Installation\n\nYou can use `Go` to install this package for you:\n\n\tgo get -u github.com/mwat56/apachelogger\n\n## Usage\n\nTo include the automatic logging facility you just call the `Wrap()` function as shown here:\n\n\tfunc main() {\n\t\t// the filenames should be taken from the commandline\n\t\t// or a config file:\n\t\taccessLog := \"/dev/stdout\"\n\t\terrorLog := \"/dev/stderr\"\n\n\t\tpageHandler := http.NewServeMux()\n\t\tpageHandler.HandleFunc(\"/\", myHandler)\n\n\t\tserver := http.Server{\n\t\t\tAddr:    \"127.0.0.1:8080\",\n\t\t\tHandler: apachelogger.Wrap(pageHandler, accessLog, errorLog),\n\t\t\t//       ^^^^^^^^^^^^^^^^^^\n\t\t}\n\t\tapachelogger.SetErrLog(\u0026server)\n\n\t\tif err := server.ListenAndServe(); nil != err {\n\t\t\tlog.Fatalf(\"%s: %v\", os.Args[0], err)\n\t\t}\n\t} // main()\n\nSo, you just have to find a way the get/set the name of the desired logfile names – e.g. via a commandline option, or an environment variable, or a config file, whatever suits you best.\nThen you set up your `server` like shown above using the call to `apachelogger.Wrap()` to wrap your original pagehandler with the logging facility.\n\nThe creation pattern for a logfile entry is this:\n\n\tapacheFormatPattern = `%s - %s [%s] \"%s %s %s\" %d %d \"%s\" \"%s\"`\n\nAll the placeholders to be seen in the pattern will be filled in with the appropriate values at runtime which are (in order of appearance):\n\n* remote IP,\n* remote user,\n* date/time of request,\n* request method,\n* requested URL,\n* request protocol,\n* server status,\n* served size,\n* remote referrer,\n* remote user agent.\n\nIt means you can now use all the logfile analysers etc. for `Apache` logs for your own logfiles as well.\n\n## Special Features\n\nSince _**privacy**_ became a serious concern for a growing number of people (including law makers) – the IP address is definitely to be considered as _personal data_ – this logging facility _anonymises_ the requesting users by setting the host-part of the respective remote address to zero (`0`).\nThis option takes care of e.g. European servers who may _not without explicit consent_ of the users store personal data; this includes IP addresses in logfiles and elsewhere (eg. statistical data gathered from logfiles).\n\nFor debugging purposes global flag `AnonymiseErrors` (default: `false`) is provided that allows to fully (e.g. not anonymised) log all requests that cause errors (e.g. 4xx and 5xx statuses).\n\nWhile the logging of web-requests is done automatically you can _manually add entries_ to the logfile by calling\n\n\tapachelogger.Log(aSender, aMessage string)\n\nThe `aSender` argument should give some indication of from where in your program you're calling the function, and `aMessage` is the text you want to write to the logfile. To preserve the format of the log-entry neither `aSender` nor `aMessage` must contain double-quotes (`\"`).\nThe messages are logged as coming from `127.0.0.1` with an user-agent of `mwat56/apachelogger`; this should make it easy to find these messages amongst all the 'normal' ones.\n\nIf you want to automatically log your server's errors as well you'd call\n\n\tapachelogger.SetErrorLog(aServer *http.Server)\n\nduring initialisation of your program. This will write the errors thrown by the server to the errorlog passed to the `Wrap()` function.\nAdditionally you can call\n\n\tapachelogger.Err(aSender, aMessage string)\n\nfrom your own code to write a message to the error log.\n\nTo avoid that a `panic` crashes your program this module catches and `recover`s such situations.\nThe error/cause of the `panic` is written to the error logfile for later inspection.\n\n## Libraries\n\nNo external libraries were used building `ApacheLogger`.\n\n## Licence\n\n        Copyright © 2019, 2025  M.Watermann, 10247 Berlin, Germany\n                        All rights reserved\n                    EMail : \u003csupport@mwat.de\u003e\n\n\u003e This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.\n\u003e\n\u003e This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\u003e\n\u003e You should have received a copy of the GNU General Public License along with this program. If not, see the [GNU General Public License](http://www.gnu.org/licenses/gpl.html) for details.\n\n----\n[![GFDL](https://www.gnu.org/graphics/gfdl-logo-tiny.png)](http://www.gnu.org/copyleft/fdl.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmwat56%2Fapachelogger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmwat56%2Fapachelogger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmwat56%2Fapachelogger/lists"}