{"id":23006668,"url":"https://github.com/aaronvb/logrequest","last_synced_at":"2025-08-20T15:16:38.556Z","repository":{"id":48815904,"uuid":"252116967","full_name":"aaronvb/logrequest","owner":"aaronvb","description":"Go HTTP request middleware that logs started and completed info, inspired by Ruby on Rails logging.","archived":false,"fork":false,"pushed_at":"2023-08-02T21:29:27.000Z","size":33,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-21T22:38:20.554Z","etag":null,"topics":["benchmark","go","golang","http","logging","logrequest","middleware","rails-log","requests"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aaronvb.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-01T08:31:38.000Z","updated_at":"2023-08-02T21:29:31.000Z","dependencies_parsed_at":"2024-12-15T08:23:22.051Z","dependency_job_id":null,"html_url":"https://github.com/aaronvb/logrequest","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronvb%2Flogrequest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronvb%2Flogrequest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronvb%2Flogrequest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronvb%2Flogrequest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aaronvb","download_url":"https://codeload.github.com/aaronvb/logrequest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246837685,"owners_count":20841903,"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":["benchmark","go","golang","http","logging","logrequest","middleware","rails-log","requests"],"created_at":"2024-12-15T08:13:15.555Z","updated_at":"2025-04-02T15:13:57.030Z","avatar_url":"https://github.com/aaronvb.png","language":"Go","readme":"# logrequest\n[![go.dev Reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go\u0026logoColor=white\u0026style=flat)](https://pkg.go.dev/github.com/aaronvb/logrequest) [![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/aaronvb/logrequest/go.yml?label=tests)](https://github.com/aaronvb/logrequest/actions/workflows/go.yml)\n\nThis is a Go middleware log output inspired by the Ruby on Rails log output for requests. Example output:\n\n```sh\nStarted GET \"/\" 127.0.0.1:12345 HTTP/1.1\nCompleted 200 in 3.7455ms\n```\n\n## Install\n```sh\ngo get -u github.com/aaronvb/logrequest\n```\n\n## Using logrequest\nThe three ways you can have logrequest return request data:\n\n- `ToLogger(logger *log.Logger)` directly sends to a `log.Logger`.\n- `ToString()` returns a `map[string]string` with the key `started` and `completed`.\n- `ToFields()` returns a `RequestFields` struct that contains the fields in the request. (See below)\n```go\ntype RequestFields struct {\n\tMethod        string\n\tUrl           string\n\tRemoteAddress string\n\tProtocol      string\n\tTime          time.Time\n\tDuration      time.Duration\n\tStatusCode    int\n}\n```\n\n## Options\nThere are two optional options you can pass to the `LogRequest` struct:\n\n#### `NewLine` (integer) - This will append N lines at the end of the log output. Note: This only works with logger output.\n\nExample:\n```go\nlr := logrequest.LogRequest{Request: r, Writer: w, Handler: next, NewLine: 2}\n```\n```\nStarted GET \"/\" 127.0.0.1:12345 HTTP/1.1\nCompleted 200 in 3.7455ms\n\n\nStarted GET \"/home\" 127.0.0.1:12345 HTTP/1.1\nCompleted 200 in 1.891ms\n```\n\n#### `Timestamp` (boolean) - This will add a timestamp at the beginning of the request.\n\nExample:\n```go\nlr := logrequest.LogRequest{Request: r, Writer: w, Handler: next, Timestamp: true}\n```\n```\nStarted GET \"/home\" 1.1.1.1:1234 HTTP/1.1 at 2020-05-13 02:25:33\n```\n\n#### `HideDuration` (boolean) - This will hide the duration at the end of the request.\n\nExample:\n```go\nlr := logrequest.LogRequest{Request: r, Writer: w, Handler: next, Timestamp: true, HideDuration: true}\n```\n```\nStarted GET \"/home\" 127.0.0.1:12345 HTTP/1.1\nCompleted 200\n```\n\n## Middleware Example (using [gorilla/mux](https://github.com/gorilla/mux))\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/aaronvb/logrequest\"\n\n\t\"github.com/gorilla/mux\"\n)\n\ntype application struct {\n\terrorLog *log.Logger\n\tinfoLog  *log.Logger\n}\n\nfunc main() {\n\tinfoLog := log.New(os.Stdout, \"INFO\\t\", log.Ldate|log.Ltime)\n\terrorLog := log.New(os.Stderr, \"ERROR\\t\", log.Ldate|log.Ltime|log.Lshortfile)\n\n\tapp := \u0026application{\n\t\terrorLog: errorLog,\n\t\tinfoLog:  infoLog,\n\t}\n\n\tsrv := \u0026http.Server{\n\t\tAddr:     \":8080\",\n\t\tErrorLog: errorLog,\n\t\tHandler:  app.routes(),\n\t}\n\n\tinfoLog.Printf(\"Starting server on %s\", \":8080\")\n\terr := srv.ListenAndServe()\n\terrorLog.Fatal(err)\n}\n\nfunc (app *application) routes() http.Handler {\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/foobar\", app.foobar).Methods(\"GET\")\n\n\t// Middleware\n\tr.Use(app.logRequest)\n\n\treturn r\n}\n\nfunc (app *application) foobar(w http.ResponseWriter, r *http.Request) {\n\ttime.Sleep(300 * time.Millisecond)\n\tfmt.Fprintln(w, \"Hello world\")\n}\n\n// Middleware\n\nfunc (app *application) logRequest(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tlr := logrequest.LogRequest{Request: r, Writer: w, Handler: next}\n\t\tlr.ToLogger(app.infoLog)\n\t})\n}\n```\n\n```sh\n\u003e go run main.go\nINFO\t2020/03/31 22:40:09 Starting server on :8080\nINFO\t2020/03/31 22:40:13 Started GET \"/foobar\" [::1]:55044 HTTP/1.1\nINFO\t2020/03/31 22:40:13 Completed 200 in 300.131639ms\nINFO\t2020/03/31 22:40:18 Started GET \"/foobar\" [::1]:55044 HTTP/1.1\nINFO\t2020/03/31 22:40:18 Completed 200 in 302.047625ms\n```\n\n## Showing Parameters\n```sh\nINFO\t2020/03/31 22:40:13 Started GET \"/foobar\" [::1]:55044 HTTP/1.1\nINFO\t2020/03/31 22:40:13 Parameters: {\"foo\" =\u003e \"bar\"}\nINFO\t2020/03/31 22:40:13 Completed 200 in 300.131639ms\n```\nCheck out my other middleware package to output incoming parameters, which is also influenced by the Ruby on Rails logger:  [https://github.com/aaronvb/logparams](https://github.com/aaronvb/logparams)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronvb%2Flogrequest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faaronvb%2Flogrequest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronvb%2Flogrequest/lists"}