{"id":22296762,"url":"https://github.com/webklex/gohits","last_synced_at":"2025-03-25T22:41:00.363Z","repository":{"id":71427903,"uuid":"294530579","full_name":"Webklex/gohits","owner":"Webklex","description":"An easy way to track your page or project views (\"hits\") of any GitHub or online project.","archived":false,"fork":false,"pushed_at":"2020-09-24T17:33:19.000Z","size":95,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-30T19:55:47.427Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hits.webklex.com","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/Webklex.png","metadata":{"files":{"readme":"README.md","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":"2020-09-10T21:52:40.000Z","updated_at":"2021-09-18T00:21:58.000Z","dependencies_parsed_at":"2023-02-25T18:31:08.643Z","dependency_job_id":null,"html_url":"https://github.com/Webklex/gohits","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Webklex%2Fgohits","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Webklex%2Fgohits/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Webklex%2Fgohits/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Webklex%2Fgohits/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Webklex","download_url":"https://codeload.github.com/Webklex/gohits/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245556961,"owners_count":20634888,"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":[],"created_at":"2024-12-03T17:47:30.169Z","updated_at":"2025-03-25T22:41:00.345Z","avatar_url":"https://github.com/Webklex.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoHits visitor counter\n\n[![Hits][ico-hits]][link-website]\n[![Total Downloads][ico-downloads]][link-releases]\n[![Latest Stable Version][ico-version]][link-releases]\n[![License][ico-license]](LICENSE.md)\n[![Website status][ico-status]][link-website]\n\n## Description\nAn easy way to track your page or project views (\"hits\") of any GitHub or online project.\n\nGenerate your own: [hits.webklex.com](https://hits.webklex.com)\n\n## Table of Contents\n- [Features](#features)\n- [Installation](#installation)\n- [Configuration](#server-options)\n  - [HTTP \u0026 HTTPS](#http--https)\n  - [Letsencrypt](#letsencrypt)\n  - [Middlewares \u0026 Extensions](#middlewares--extensions)\n  - [Rate limiting \u0026 Quota management](#rate-limiting--quota-management)\n  - [Logging](#logging)\n  - [Additional](#additional)\n- [Api](#api)\n  - [Output](#output)\n    - [CSV](#csv)\n    - [XML](#xml)\n    - [JSON](#json)\n  - [Websocket](#websocket)\n- [Build](#build)\n- [Service](#service)\n- [Support](#support)\n- [Security](#security)\n- [Credits](#credits)\n- [License](#license)\n\n### Features\n* Serving over HTTPS (TLS) using your own certificates, or provisioned automatically using [LetsEncrypt.org](https://letsencrypt.org)\n* [HSTS ready](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) to restrict your browser clients to always use HTTPS\n* Configurable read and write timeouts to avoid stale clients consuming server resources\n* Reverse proxy ready\n* Configurable [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) to restrict access to specific domains\n* Configurable api prefix to serve the API alongside other APIs on the same host\n* Optional round trip optimization by enabling [TCP Fast Open](https://en.wikipedia.org/wiki/TCP_Fast_Open)\n* Integrated rate limit (quota) for your clients (per client IP) based on requests per time interval; several backends such as in-memory map (for single instance), or redis or memcache for distributed deployments are supported\n\n### Installation\nDownload and unpack a fitting [pre-compiled binary](https://github.com/webklex/gohits/releases) or build a binary \nyourself by by following the [build](#build) instructions.\n\nContinue by configuring your application:\n```bash\ngohits -http=:8080 -gui gui -save\n```\nOpen a browser and navigate to `http://localhost:8080/` to verify everything is working.\n\nPlease take a look at the available [options](#server-options) for further details.\n\n### Server Options\nTo see all the available options, use the `-help` option:\n```bash\ngohits -help\n```\n                        |\n\n#### HTTP \u0026 HTTPS\n| CLI                    | Config               | Type   | Default              | Description                                                 |\n| :--------------------- | :------------------- | :----- | :------------------- | :---------------------------------------------------------- |\n| -http                  | HTTP                 | string | localhost:8080       | Address in form of ip:port to listen                        |\n| -https                 | HTTPS                | string |                      | Address in form of ip:port to listen                        |\n| -write-timeout         | WRITE_TIMEOUT        | int    | 15000000000          | Write timeout in nanoseconds for HTTP and HTTPS client connections |\n| -read-timeout          | READ_TIMEOUT         | int    | 30000000000          | Read timeout in nanoseconds for HTTP and HTTPS client connections |\n| -tcp-fast-open         | TCP_FAST_OPEN        | bool   | false                | Enable TCP fast open                                        |\n| -tcp-naggle            | TCP_NAGGLE           | bool   | false                | Enable TCP Nagle's algorithm                                |\n| -http2                 | HTTP2                | bool   | true                 | Enable HTTP/2 when TLS is enabled                           |\n| -hsts                  | HSTS                 | string |                      |                                                             |\n| -key                   | KEY                  | string | key.pem              | X.509 key file for HTTPS server                             |\n| -cert                  | CERT                 | string | cert.pem             | X.509 certificate file for HTTPS server                     |\n\n#### Letsencrypt\n| CLI                    | Config               | Type   | Default              | Description                                                 |\n| :--------------------- | :------------------- | :----- | :------------------- | :---------------------------------------------------------- |\n| -letsencrypt           | LETSENCRYPT          | bool   | false                | Enable automatic TLS using letsencrypt.org                  |\n| -letsencrypt-email     | LETSENCRYPT_EMAIL    | string |                      | Optional email to register with letsencrypt                 |\n| -letsencrypt-hosts     | LETSENCRYPT_HOSTS    | string |                      | Comma separated list of hosts for the certificate           |\n| -letsencrypt-cert-dir  | LETSENCRYPT_CERT_DIR | string |                      | Letsencrypt cert dir                                        |\n\n#### Middlewares \u0026 Extensions\n| CLI                    | Config               | Type   | Default              | Description                                                 |\n| :--------------------- | :------------------- | :----- | :------------------- | :---------------------------------------------------------- |\n| -use-x-forwarded-for   | USE_X_FORWARDED_FOR  | bool   | false                | Use the X-Forwarded-For header when available (e.g. behind proxy) |\n| -cors-origin           | CORS_ORIGIN          | string | *                    | Comma separated list of CORS origins endpoints              |\n| -api-prefix            | API_PREFIX           | string | /                    | API endpoint prefix                                         |\n| -gui                   | GUI                  | string |                      | Web gui directory                                           |\n| -session-lifetime      | SESSION_LIFETIME     | int    | 1200000000000        | Session lifetime of an counted visitor (default 20min)      |\n| -pong-wait             | PONG_WAIT            | int    | 24000000000          | Time allowed to read the next pong message from the peer. (default 24s) |\n| -ping-period           | PING_PERIOD          | int    | 12000000000          | Send pings to peer with this period. Must be less than pong-wait. (default 12s) |\n\n##### Rate limiting \u0026 Quota management\n| CLI                    | Config               | Type   | Default              | Description                                                 |\n| :--------------------- | :------------------- | :----- | :------------------- | :---------------------------------------------------------- |\n| -quota-burst           | QUOTA_BURST          | int    | 3                    | Max requests per source IP per request burst                |\n| -quota-interval        | QUOTA_INTERVAL       | int    | 3600000000000        | Quota expiration interval, per source IP querying the API in nanoseconds |\n| -quota-max             | QUOTA_MAX            | int    | 1                    | \"Max requests per source IP per interval; set 0 to turn quotas off |\n\n#### Logging\n| CLI                    | Config               | Type   | Default              | Description                                                 |\n| :--------------------- | :------------------- | :----- | :------------------- | :---------------------------------------------------------- |\n| -logtostdout           | LOGTOSTDOUT          | bool   | false                | Log to stdout instead of stderr                             |\n| -log-file              | LOG_FILE             | string |                      | Log file location                             |\n| -logtimestamp          | LOGTIMESTAMP         | bool   | true                 | Prefix non-access logs with timestamp                       |\n\n#### Additional\n| CLI                    | Config               | Type   | Default              | Description                                                 |\n| :--------------------- | :------------------- | :----- | :------------------- | :---------------------------------------------------------- |\n| -silent                | SILENT               | bool   | false                | Disable HTTP and HTTPS log request details                  |\n| -config                |                      | string | conf/settings.config | Config file path                                            |\n| -save                  |                      | bool   | false                | Save config                                                 |\n| -version               |                      | bool   | false                | Show version and exit                                       |\n| -help                  |                      | bool   | false                | Show help and exit                                          |\n\nIf you're using LetsEncrypt.org to provision your TLS certificates, you have to listen for HTTPS on port 443. Following \nis an example of the server listening on 2 different ports: http (80) and https (443):\n```bash\ngohits \\\n    -http=:8080 \\\n    -https=:8443 \\\n    -hsts=max-age=31536000 \\\n    -letsencrypt \\\n    -letsencrypt-hosts=example.com \\\n    -gui gui \\\n    -save\n```\n\n```bash\n$ cat conf/settings.config\n{\n    \"HTTP\": \":8080\",\n    \"HTTPS\": \":8443\",\n    \"HSTS\": \"max-age=31536000\",\n    \"LETSENCRYPT\": true,\n    \"LETSENCRYPT_HOSTS\": \"example.com\",\n    ...\n```\n\nBy default, HTTP/2 is enabled over HTTPS. You can disable by passing the `-http2=false` flag.\n\nIf the web server is running behind a reverse proxy or load balancer, you have to run it passing the `-use-x-forwarded-for` \nparameter and provide the `X-Forwarded-For` HTTP header in all requests. This is for the gohits web server be able to log the \nclient IP, and to perform correctly identify new hits.\n\n## API\nThe API is served by endpoints that encode the response in different formats.\n\n```bash\ncurl :8080/json/{username}/{repository}\n```\nSame semantics are available for the `/xml/{username}/{repository}` and `/csv/{username}/{repository}` endpoints.\n\n### Output\n#### Section\n| Name                  | Value type    | JSON                      | XML                   | CSV   |\n| :-------------------- | :------------ | :------------------------ | :-------------------- | :---- |\n| Username              | string        | username                  | Username              | 0     |\n| Repository            | string        | repository                | Repository            | 1     |\n| Total                 | int           | total                     | Total                 | 2     |\n| Created at            | datetime      | created_at                | CreatedAt             | 3     |\n| Updated at            | datetime      | updated_at                | UpdatedAt             | 4     |\n\n#### CSV\n```bash\ncurl :8080/csv/webklex/gohits\n```\n```\nwebklex,gohits,55,2020-09-11 07:01:23,2020-09-12 00:10:07\n```\n\n#### XML\n```bash\ncurl :8080/xml/webklex/gohits\n```\n```xml\n\u003cSection\u003e\n    \u003cUsername\u003ewebklex\u003c/Username\u003e\n    \u003cRepository\u003egohits\u003c/Repository\u003e\n    \u003cTotal\u003e55\u003c/Total\u003e\n    \u003cCreatedAt\u003e2020-09-11T07:01:23.252745204+02:00\u003c/CreatedAt\u003e\n    \u003cUpdatedAt\u003e2020-09-12T00:10:07.7275806+02:00\u003c/UpdatedAt\u003e\n\u003c/Section\u003e\n```\n\n#### JSON\n```bash\ncurl :8080/json/webklex/gohits\n```\n```json\n{\n  \"username\": \"webklex\",\n  \"repository\": \"gohits\",\n  \"total\": 55,\n  \"created_at\": \"2020-09-11T07:01:23.252745204+02:00\",\n  \"updated_at\": \"2020-09-12T00:10:07.7275806+02:00\"\n}\n```\n\n### Websocket\nUrl: `:8080/ws`\n\nYou can subscribe to specific channels or to `all` in order to receive all recent hits.\n\n#### Payloads:\n**Subscribe to channel `all`:**\n```json\n{\n  \"name\": \"subscribe\",\n  \"payload\": \"all\"\n}\n```\n**Subscribe to channel `webklex/gohits`:**\n```json\n{\n  \"name\": \"subscribe\",\n  \"payload\": \"webklex/gohits\"\n}\n```\n**Delete a the subscription of `all`:**\n```json\n{\n  \"name\": \"unsubscribe\",\n  \"payload\": \"all\"\n}\n```\n#### Output\n```\n00:26:07 webklex/gohits\n```\n\n\n### Build\nYou can build your own binaries by calling `build.sh`\n```bash\nbuild.sh build_dir\n```\n\n### Service\nCreate a new file like `/etc/systemd/system/gohits.service` and add the following:\n```\n[Unit]\nDescription=GoHits\nAfter=multi-user.target\nAfter=syslog.target\nAfter=network-online.target\n\n[Service]\nType=simple\n\nUser=www-data\nGroup=www-data\n\nWorkingDirectory=/opt/gohits\nExecStart=/opt/gohits/gohits\n\nRestart=on-failure\nRestartSec=5s\n\n[Install]\nWantedBy=multi-user.target\n```\n\nStart the service and check for any errors.\n```bash\nsystemctl start gohits.service\n```\n\n### Features \u0026 pull requests\nEveryone can contribute to this project. Every pull request will be considered but it can also happen to be declined. \nTo prevent unnecessary work, please consider to create a [feature issue](https://github.com/webklex/gohits/issues/new?template=feature_request.md) \nfirst, if you're planning to do bigger changes. Of course you can also create a new [feature issue](https://github.com/webklex/gohits/issues/new?template=feature_request.md)\nif you're just wishing a feature ;)\n\n\u003eOff topic, rude or abusive issues will be deleted without any notice.\n\n\n## Support\nIf you encounter any problems or if you find a bug, please don't hesitate to create a new [issue](https://github.com/webklex/gohits/issues).\nHowever please be aware that it might take some time to get an answer.\n\nIf you need **immediate** or **commercial** support, feel free to send me a mail at github@webklex.com. \n\n## Change log\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Security\n\nIf you discover any security related issues, please email github@webklex.com instead of using the issue tracker.\n\n## Credits\n- [Webklex][link-author]\n- [All Contributors][link-contributors]\n\n## License\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n\n[ico-hits]: https://hits.webklex.com/svg/webklex/gohits?\n[ico-downloads]: https://img.shields.io/github/downloads/webklex/gohits/total?style=flat-square\n[ico-version]: https://img.shields.io/github/v/release/webklex/gohits?style=flat-square\n[ico-license]: https://img.shields.io/github/license/webklex/gohits?style=flat-square\n[ico-status]: https://img.shields.io/website?down_message=Offline\u0026label=Website\u0026style=flat-square\u0026up_message=Online\u0026url=https%3A%2F%2Fhits.webklex.com%2F\n\n[link-website]: https://hits.webklex.com\n[link-releases]: https://github.com/webklex/gohits/releases\n[link-author]: https://github.com/webklex\n[link-contributors]: https://github.com/webklex/gohits/graphs/contributors\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebklex%2Fgohits","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebklex%2Fgohits","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebklex%2Fgohits/lists"}