{"id":18084871,"url":"https://github.com/jwodder/apachelogs","last_synced_at":"2025-04-09T15:07:06.301Z","repository":{"id":57410818,"uuid":"184947836","full_name":"jwodder/apachelogs","owner":"jwodder","description":"Parse Apache access logs","archived":false,"fork":false,"pushed_at":"2025-04-07T13:13:02.000Z","size":205,"stargazers_count":27,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T15:06:52.573Z","etag":null,"topics":["access-logs","apache","available-on-pypi","httpd","logfiles","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","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/jwodder.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","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":"2019-05-04T21:53:25.000Z","updated_at":"2025-02-12T04:47:39.000Z","dependencies_parsed_at":"2023-01-31T01:55:12.839Z","dependency_job_id":"e517110b-452b-4e04-b195-113670988d4e","html_url":"https://github.com/jwodder/apachelogs","commit_stats":{"total_commits":185,"total_committers":3,"mean_commits":"61.666666666666664","dds":"0.032432432432432434","last_synced_commit":"a48f4c3e3d7cc95a50f220aaf8aa5c1823719f0c"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fapachelogs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fapachelogs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fapachelogs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fapachelogs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jwodder","download_url":"https://codeload.github.com/jwodder/apachelogs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248055284,"owners_count":21040157,"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":["access-logs","apache","available-on-pypi","httpd","logfiles","python"],"created_at":"2024-10-31T15:08:28.407Z","updated_at":"2025-04-09T15:07:06.285Z","avatar_url":"https://github.com/jwodder.png","language":"Python","readme":"|repostatus| |ci-status| |coverage| |pyversions| |license|\n\n.. |repostatus| image:: https://www.repostatus.org/badges/latest/active.svg\n    :target: https://www.repostatus.org/#active\n    :alt: Project Status: Active — The project has reached a stable, usable\n          state and is being actively developed.\n\n.. |ci-status| image:: https://github.com/jwodder/apachelogs/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/jwodder/apachelogs/actions/workflows/test.yml\n    :alt: CI Status\n\n.. |coverage| image:: https://codecov.io/gh/jwodder/apachelogs/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/jwodder/apachelogs\n\n.. |pyversions| image:: https://img.shields.io/pypi/pyversions/apachelogs.svg\n    :target: https://pypi.org/project/apachelogs/\n\n.. |license| image:: https://img.shields.io/github/license/jwodder/apachelogs.svg\n    :target: https://opensource.org/licenses/MIT\n    :alt: MIT License\n\n`GitHub \u003chttps://github.com/jwodder/apachelogs\u003e`_\n| `PyPI \u003chttps://pypi.org/project/apachelogs/\u003e`_\n| `Documentation \u003chttps://apachelogs.readthedocs.io\u003e`_\n| `Issues \u003chttps://github.com/jwodder/apachelogs/issues\u003e`_\n| `Changelog \u003chttps://github.com/jwodder/apachelogs/blob/master/CHANGELOG.md\u003e`_\n\n``apachelogs`` parses Apache access log files.  Pass it a `log format string\n\u003chttp://httpd.apache.org/docs/current/mod/mod_log_config.html\u003e`_ and get back a\nparser for logfile entries in that format.  ``apachelogs`` even takes care of\ndecoding escape sequences and converting things like timestamps, integers, and\nbare hyphens to ``datetime`` values, ``int``\\s, and ``None``\\s.\n\n\nInstallation\n============\n``apachelogs`` requires Python 3.8 or higher.  Just use `pip\n\u003chttps://pip.pypa.io\u003e`_ for Python 3 (You have pip, right?) to install\n``apachelogs`` and its dependencies::\n\n    python3 -m pip install apachelogs\n\n\nExamples\n========\n\nParse a single log entry:\n\n\u003e\u003e\u003e from apachelogs import LogParser\n\u003e\u003e\u003e parser = LogParser(\"%h %l %u %t \\\"%r\\\" %\u003es %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\")\n\u003e\u003e\u003e # The above log format is also available as the constant `apachelogs.COMBINED`.\n\u003e\u003e\u003e entry = parser.parse('209.126.136.4 - - [01/Nov/2017:07:28:29 +0000] \"GET / HTTP/1.1\" 301 521 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36\"\\n')\n\u003e\u003e\u003e entry.remote_host\n'209.126.136.4'\n\u003e\u003e\u003e entry.request_time\ndatetime.datetime(2017, 11, 1, 7, 28, 29, tzinfo=datetime.timezone.utc)\n\u003e\u003e\u003e entry.request_line\n'GET / HTTP/1.1'\n\u003e\u003e\u003e entry.final_status\n301\n\u003e\u003e\u003e entry.bytes_sent\n521\n\u003e\u003e\u003e entry.headers_in[\"Referer\"] is None\nTrue\n\u003e\u003e\u003e entry.headers_in[\"User-Agent\"]\n'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'\n\u003e\u003e\u003e # Log entry components can also be looked up by directive:\n\u003e\u003e\u003e entry.directives[\"%r\"]\n'GET / HTTP/1.1'\n\u003e\u003e\u003e entry.directives[\"%\u003es\"]\n301\n\u003e\u003e\u003e entry.directives[\"%t\"]\ndatetime.datetime(2017, 11, 1, 7, 28, 29, tzinfo=datetime.timezone.utc)\n\nParse a file full of log entries:\n\n\u003e\u003e\u003e with open('/var/log/apache2/access.log') as fp:  # doctest: +SKIP\n...     for entry in parser.parse_lines(fp):\n...         print(str(entry.request_time), entry.request_line)\n...\n2019-01-01 12:34:56-05:00 GET / HTTP/1.1\n2019-01-01 12:34:57-05:00 GET /favicon.ico HTTP/1.1\n2019-01-01 12:34:57-05:00 GET /styles.css HTTP/1.1\n# etc.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwodder%2Fapachelogs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwodder%2Fapachelogs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwodder%2Fapachelogs/lists"}