{"id":51124539,"url":"https://github.com/GetPageSpeed/ngx-sqlite-log","last_synced_at":"2026-06-25T06:01:27.759Z","repository":{"id":277485763,"uuid":"932566810","full_name":"GetPageSpeed/ngx-sqlite-log","owner":"GetPageSpeed","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-14T06:08:02.000Z","size":102,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-05-09T15:48:20.007Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GetPageSpeed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2025-02-14T05:51:03.000Z","updated_at":"2025-02-14T06:07:16.000Z","dependencies_parsed_at":"2025-02-14T07:22:14.074Z","dependency_job_id":"5cffca99-dd77-469e-9dcc-9ddedb5d44ac","html_url":"https://github.com/GetPageSpeed/ngx-sqlite-log","commit_stats":null,"previous_names":["getpagespeed/ngx-sqlite-log"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/GetPageSpeed/ngx-sqlite-log","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx-sqlite-log","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx-sqlite-log/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx-sqlite-log/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx-sqlite-log/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GetPageSpeed","download_url":"https://codeload.github.com/GetPageSpeed/ngx-sqlite-log/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx-sqlite-log/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34761847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-25T06:01:23.870Z","updated_at":"2026-06-25T06:01:27.747Z","avatar_url":"https://github.com/GetPageSpeed.png","language":"C","funding_links":[],"categories":["Logging and observability"],"sub_categories":[],"readme":"# ngx-sqlitelog\n* [Summary](#summary)\n* [Directives](#directives)\n    * [sqlitelog](#sqlitelog)\n    * [sqlitelog_format](#sqlitelog_format)\n    * [sqlitelog_async](#sqlitelog_async)\n* [Install](#install)\n* [Example](#example)\n* [Errors](#errors)\n* [Usage](#usage)\n    * [Locations](#locations)\n    * [Inheritance](#inheritance)\n    * [WAL mode](#wal-mode)\n    * [Logrotate](#logrotate)\n    * [Column types](#column-types)\n\n## Summary\n\nThis module uses SQLite format for access logs.\nGitHub fork of https://git.serope.com/me/ngx-sqlitelog\n\n## Installation\n\nRPM-based systems:\n\n```bash\ndnf -y install https://extras.getpagespeed.com/release-latest.rpm \ndnf -y install nginx-module-log-sqlite\n```\n\nEnable the module by adding the following at the top of `/etc/nginx/nginx.conf`:\n\n```nginx\nload_module modules/ngx_http_sqlitelog_module.so;\n```\n\n### Configuration Example\n\n```nginx\nhttp {\n    sqlitelog_format  myformat $remote_addr $time_local $host $request_uri $request_time $status;\n    sqlitelog         /tmp/access.db myformat buffer=128K max=5;\n    ...\n    server {\n        ...\n    }\n}\n```\n\nA few requests later...\n\n```sh\n$ sqlite3 /tmp/access.db \".mode columns\" \".headers on\" \"SELECT * FROM myformat WHERE remote_addr='192.168.1.1'\"\nremote_addr  time_local                  host        request_uri                    request_time  status\n-----------  --------------------------  ----------  -----------------------------  ------------  ------\n192.168.1.1  07/Jan/2024:08:28:09 -0500  serope.com  /                              0.0           200   \n192.168.1.1  07/Jan/2024:08:28:09 -0500  serope.com  /css/base.min.css              0.0           200   \n192.168.1.1  07/Jan/2024:08:28:09 -0500  serope.com  /index.js                      0.0           200   \n192.168.1.1  07/Jan/2024:08:28:09 -0500  serope.com  /js/modules/bullet-list.js     0.0           200   \n192.168.1.1  07/Jan/2024:08:28:09 -0500  serope.com  /bullet-lists/software.json    0.0           200   \n192.168.1.1  07/Jan/2024:08:28:09 -0500  serope.com  /bullet-lists/misc.json        0.0           200   \n192.168.1.1  07/Jan/2024:08:28:09 -0500  serope.com  /favicon.ico                   0.0           200   \n192.168.1.1  07/Jan/2024:08:28:10 -0500  serope.com  /banner-links.json             0.0           200   \n192.168.1.1  07/Jan/2024:08:28:13 -0500  serope.com  /gpu/websocket?check=          3.108         502   \n192.168.1.1  07/Jan/2024:08:28:14 -0500  serope.com  /gpu/                          0.0           200   \n192.168.1.1  07/Jan/2024:08:28:14 -0500  serope.com  /gpu/style.css                 0.0           200   \n192.168.1.1  07/Jan/2024:08:28:14 -0500  serope.com  /gpu/index.js                  0.0           200   \n192.168.1.1  07/Jan/2024:08:28:14 -0500  serope.com  /gpu/smoothie.js               0.0           200   \n192.168.1.1  07/Jan/2024:08:28:14 -0500  serope.com  /gpu/modules/watch-window.js   0.0           200   \n192.168.1.1  07/Jan/2024:08:28:14 -0500  serope.com  /gpu/modules/watch-window.css  0.0           200   \n192.168.1.1  07/Jan/2024:08:28:16 -0500  serope.com  /gpu/websocket                 2.079         502  \n```\n\n## Directives\n\n### sqlitelog\n\n* Syntax: `sqlitelog` *`path`* \u003ccode\u003e[\u003ci\u003eformat\u003c/i\u003e]\u003c/code\u003e \u003ccode\u003e[buffer=\u003ci\u003esize\u003c/i\u003e [max=\u003ci\u003en\u003c/i\u003e] [flush=\u003ci\u003etime\u003c/i\u003e]]\u003c/code\u003e  \u003ccode\u003e[init=\u003ci\u003escript\u003c/i\u003e]\u003c/code\u003e \u003ccode\u003e[if=\u003ci\u003econdition\u003c/i\u003e]\u003c/code\u003e | `off`\n* Default: `sqlitelog` `off`\n* Context: http, server\n\nThis directive defines a logging database.\n\nThe *`path`* parameter is the path of the database file. It must be located in a directory where the user or group that owns Nginx worker processes (defined by the [`user` directive](https://nginx.org/en/docs/ngx_core_module.html#user)) has write permission so that it can create the database file and any possible [temporary files](https://sqlite.org/tempfiles.html).\n\nThe *`format`* parameter is the name of a log format defined by the `sqlitelog_format` directive. If not given, the default combined format is used.\n\nThe `buffer` parameter creates a memory zone where log entries are batched together and written to the database in a single `BEGIN` ... `COMMIT` transaction. This greatly improves performance as grouped inserts [are faster](https://www.sqlite.org/faq.html#q19) than separate ones. The buffer is commited when one of the following happens: its *`size`* is exceeded; it accumulates *`n`* log entries; the flush *`time`* elapses; Nginx reloads or exits.\n\nThe `init` parameter is a path to a SQL script file which is executed on each database connection. This can be used to run [pragma commands](https://www.sqlite.org/pragma.html#toc) or to create additional tables, views, and triggers to complement the logging table; such statements should include `IF NOT EXISTS` since they can be executed more than once.\n\nThe `if` parameter sets a logging condition. Like in the standard [log module](https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log), if *`condition`* evaluates to 0 or an empty string, logging is skipped for the current request.\n\n### sqlitelog_format\n\n* Syntax: `sqlitelog_format` *`table`* *`var1`* \u003ccode\u003e[\u003ci\u003etype1\u003c/i\u003e]\u003c/code\u003e *`var2`* \u003ccode\u003e[\u003ci\u003etype2\u003c/i\u003e]\u003c/code\u003e ... *`varN`* \u003ccode\u003e[\u003ci\u003etypeN\u003c/i\u003e]\u003c/code\u003e\n* Default: `sqlitelog_format` `combined` `$remote_addr` `$remote_user` `$time_local` `$request` `$status` `$body_bytes_sent` `$http_referer` `$http_user_agent`\n* Context: http\n\nThis directive defines a logging table.\n\nThe first argument is the table's name. The remaining arguments are variables with optional column types. Some variables have [preset column types](#column-types), otherwise the default is `TEXT`. If a variable is `BLOB` type, its value is written as unescaped bytes.\n\n### sqlitelog_async\n\n* Syntax: `sqlitelog_async` *`pool`* | `on` | `off`\n* Default: `sqlitelog_async` `off`\n* Context: http\n\nThis directive enables a [thread pool](https://nginx.org/en/docs/ngx_core_module.html#thread_pool), allowing SQLite file writes to occur without blocking. The argument can be an existing *`pool`* name, `on` for the default pool, or `off`. This directive is only available if Nginx is compiled with `--with-threads`.\n\n## Errors\n\nWhen a SQLite error occurs, the module is disabled (equivalent to `sqlitelog off`) for the worker process that encountered the error. This is to prevent error.log from being quickly flooded with error messages if the database is unusable (e.g. located in a directory where worker processes don't have write permission).\n\n* [SQLITE_ERROR (1)](https://www.sqlite.org/rescode.html#error): This is a generic error code that covers several cases, such as SQL syntax errors in an `init` script.\n* [SQLITE_BUSY (5)](https://www.sqlite.org/rescode.html#busy): Multiple worker processes attempted to use the database simultaneously and exceeded the busy timeout (1000 ms by default). This can be solved by creating a `buffer` to speed up insertions or by setting a longer timeout with `PRAGMA busy_timeout` in an `init` script.\n* [SQLITE_READONLY (8)](https://www.sqlite.org/rescode.html#readonly): Nginx can open the database, but can't write to it. This is likely due to file permissions.\n* [SQLITE_CANTOPEN (14)](https://www.sqlite.org/rescode.html#cantopen): Nginx can't open or create the database. This is likely due to directory permissions. The user or group that owns worker processes (defined by the [`user` directive](https://nginx.org/en/docs/ngx_core_module.html#user)) must have write permission on the directory.\n* [SQLITE_READONLY_DBMOVED (1032)](https://www.sqlite.org/rescode.html#readonly_dbmoved): The file was moved, renamed, or deleted at runtime. When this happens, Nginx attempts to recreate the file; if successful, the error is ignored and logging continues normally.\n\n## Usage\n\n### Locations\n\nThe `sqlitelog` directive can't be used in location contexts, but a regex condition can achieve a similar effect. In this example, only requests that start with \"/mylocation\" are logged.\n\n\u003c!--\nDon't forget to compile Nginx with `--with-pcre`!\n--\u003e\n\n```nginx\nmap $request_uri $is_my_loc {\n    default            0;\n    ~^/mylocation.*$   1;\n}\n\nsqlitelog access.db if=$is_my_loc;\n```\n\n### Inheritance\n\nOnly one `sqlitelog` is allowed per context, with lower contexts taking priority. In this example, requests to server A are logged to global.db, while requests to server B are logged to b.db.\n\n```nginx\nhttp {\n    sqlitelog global.db;\n    ...\n    \n    server {\n        server_name a;\n        ...\n    }\n    \n    server {\n        server_name b;\n        sqlitelog b.db;\n        ....\n    }\n````\n\n### WAL mode\n\n[WAL mode](https://www.sqlite.org/wal.html) is enabled by `PRAGMA journal_mode=wal` in an `init` script. [WAL checkpointing](https://www.sqlite.org/wal.html#ckpt) occurs when Nginx reloads or exits.\n\n### Logrotate\n\n[Logrotate](https://man.archlinux.org/man/logrotate.8) should be configured to stop Nginx, rotate logs, and start Nginx again. This way, Nginx gracefully closes its connections to the previous day's database(s) and opens new ones to the current day's database(s).\n\nBelow is an example script for Debian (`/etc/logrotate.d/nginx`). It assumes the worker process user, `www-data`, has been granted write permission on `/var/log/nginx`, which is normally only writeable by `root`.\n\n```sh\n/var/log/nginx/*.log\n/var/log/nginx/*.db\n{\n    daily\n    missingok\n    rotate 52\n    compress\n    delaycompress\n    notifempty\n    create 640 www-data adm\n    sharedscripts\n    \n    # Force Logrotate to work in this directory even though\n    # its permissions have been modified to allow a non-root\n    # user to write in it\n    su root adm\n    \n    # Send a quit signal to Nginx and wait for its PID file\n    # to be destroyed\n    firstaction\n        systemctl stop nginx.service\n        while [ -f /var/run/nginx.pid ]; do  \n            sleep 0.1s\n        done\n    endscript\n    \n    # Start Nginx again\n    lastaction\n        systemctl restart nginx.service\n    endscript\n}\n```\n\n### Column types\n\nThe following variables have preset column types, but can be overridden if needed.\n\nVariable | Type\n-------- | ----\n[$binary_remote_addr](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_binary_remote_addr) | `BLOB`\n[$body_bytes_sent](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_body_bytes_sent) | `INTEGER`\n[$bytes_sent](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_bytes_sent) | `INTEGER`\n[$connection](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_connection) | `INTEGER`\n[$connection_requests](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_connection_requests) | `INTEGER`\n[$connection_time](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_connection_time) | `REAL`\n[$connections_active](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html#var_connections_active) | `INTEGER`\n[$connections_reading](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html#var_connections_reading) | `INTEGER`\n[$connections_waiting](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html#var_connections_waiting) | `INTEGER`\n[$connections_writing](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html#var_connections_writing) | `INTEGER`\n[$content_length](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_content_length) | `INTEGER`\n[$gzip_ratio](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#var_gzip_ratio) | `REAL`\n[$limit_rate](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_limit_rate) | `INTEGER`\n[$msec](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_msec) | `REAL`\n[$pid](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_pid) | `INTEGER`\n[$proxy_port](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_port) | `INTEGER`\n[$proxy_protocol_port](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_proxy_protocol_port) | `INTEGER`\n[$proxy_protocol_server_port](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_proxy_protocol_server_port) | `INTEGER` \n[$remote_port](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_remote_port) | `INTEGER`\n[$request_time](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_time) | `REAL`\n[$server_port](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_server_port) | `INTEGER`\n[$status](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_status) | `INTEGER`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGetPageSpeed%2Fngx-sqlite-log","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FGetPageSpeed%2Fngx-sqlite-log","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGetPageSpeed%2Fngx-sqlite-log/lists"}