{"id":23898898,"url":"https://github.com/mugglewei/haclog","last_synced_at":"2025-04-09T23:22:06.670Z","repository":{"id":198863595,"uuid":"701278554","full_name":"MuggleWei/haclog","owner":"MuggleWei","description":"Haclog(Happy Aync C log) is an extremely fast plain C logging library","archived":false,"fork":false,"pushed_at":"2025-02-27T14:45:56.000Z","size":196,"stargazers_count":75,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-02T22:04:38.299Z","etag":null,"topics":["c","high-performance","logging","low-latency"],"latest_commit_sha":null,"homepage":"","language":"C","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/MuggleWei.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":"2023-10-06T09:59:48.000Z","updated_at":"2025-03-29T00:27:46.000Z","dependencies_parsed_at":"2023-10-11T14:21:15.418Z","dependency_job_id":"8dd1300d-17d7-4611-bb38-562c995da6a0","html_url":"https://github.com/MuggleWei/haclog","commit_stats":null,"previous_names":["mugglewei/haclog"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuggleWei%2Fhaclog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuggleWei%2Fhaclog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuggleWei%2Fhaclog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuggleWei%2Fhaclog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MuggleWei","download_url":"https://codeload.github.com/MuggleWei/haclog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248126504,"owners_count":21051941,"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":["c","high-performance","logging","low-latency"],"created_at":"2025-01-04T18:14:21.845Z","updated_at":"2025-04-09T23:22:06.643Z","avatar_url":"https://github.com/MuggleWei.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# haclog\n\n![linux-gcc](https://github.com/MuggleWei/haclog/actions/workflows/linux-gcc.yaml/badge.svg?branch=master)\n![linux-clang](https://github.com/MuggleWei/haclog/actions/workflows/linux-clang.yaml/badge.svg?branch=master)\n![win-msvc](https://github.com/MuggleWei/haclog/actions/workflows/win-msvc.yaml/badge.svg?branch=master)\n![macos-clang](https://github.com/MuggleWei/haclog/actions/workflows/macos-clang.yaml/badge.svg?branch=master)\n![android](https://github.com/MuggleWei/haclog/actions/workflows/android-cmake.yaml/badge.svg?branch=master)\n\n* [readme EN](./README.md)\n* [readme 中文](./README_cn.md)\n\nhaclog(**H**appy **A**sync **C** Log) is a plain C asynchronous log library. The main goal of this library is to make the writing time of **log front-end(log producer thread)** as small as possible.  \n\n\u003cimg src=\"./doc/img/haclog.svg\" /\u003e\n\n## Build\n`haclog` supports multiple build tools\n\n### cmake\n```\nmkdir build\ncd build\ncmake ..\n```\n\nIf you want to compile and run unit tests and benchmark, run `run_test_and_benchmark.sh` (in Windows, `run_test_and_benchmark.bat`)\n\n### meson\n```\nmeson setup build\nmeson compile -C build\n```\n\n## Usage samples\n### hello\n```\n#include \u003cstdlib.h\u003e\n#include \"haclog/haclog.h\"\n\nvoid add_console_handler()\n{\n\tstatic haclog_console_handler_t handler;\n\tmemset(\u0026handler, 0, sizeof(handler));\n\tif (haclog_console_handler_init(\u0026handler, 1) != 0) {\n\t\tfprintf(stderr, \"failed init console handler\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\thaclog_handler_set_level((haclog_handler_t *)\u0026handler, HACLOG_LEVEL_INFO);\n\thaclog_context_add_handler((haclog_handler_t *)\u0026handler);\n}\n\nint main()\n{\n\t// add console handler\n\tadd_console_handler();\n\n\t// run haclog backend\n\thaclog_backend_run();\n\n\t// initialize thread context\n\thaclog_thread_context_init();\n\n\tHACLOG_INFO(\"Hello World\");\n\n\tdouble pi = 3.14159265359;\n\tHACLOG_DEBUG(\"π = %.5f\", pi);\n\n\t// NOTE: assert false will crash when build type is debug\n\tint actual = 1;\n\tint expect = 1;\n\tHACLOG_ASSERT_MSG(actual == expect,\n\t\t\"actual: %d, expect: %d\", actual, expect);\n\n\t// NOTE: fatal level log will crash when build type is debug\n\tif (actual != expect) {\n\t\tHACLOG_FATAL(\"actual != expect, crash when debug\");\n\t}\n\n\t// cleanup thread context\n\thaclog_thread_context_init();\n\n\treturn 0;\n}\n```\n\n* Use `haclog_context_add_handler`, you can add different log handler into context, built-in support `handler` is as follows\n  * `haclog_console_handler_t`: output to console(stdout/stderr)\n  * `haclog_file_handler_t`: output to file\n  * `haclog_file_rotate_handler_t`: output to file and rotate according to file size\n  * `haclog_file_time_rot_handler_t`: output to file and rotate according to time\n* After add `handler`, call `haclog_backend_run` to run log backend\n* In each thread, before write log, call `haclog_thread_context_init` to initialize `haclog` thread context\n* When thread exit, call `haclog_thread_context_init` to cleanup `haclog` thread context\n\n**NOTE**: in `haclog`, the format string in each log must be a **string literal**, When using C++, the compiler will help the user to automatically detect it; when using C, the user needs to gurantee this by self  \n```\n/* Bad!!! Don't do that, format string must be a string literal */\n// char *fmt_str = NULL;\n// int v = rand();\n// if (v % 2 == 0) {\n// \tfmt_str = \"%d is even\";\n// } else {\n// \tfmt_str = \"%d is odd\";\n// }\n// HACLOG_FATAL(fmt_str, v);\n```\n\n### file handler\n```\nvoid add_file_handler()\n{\n\tstatic haclog_file_handler_t handler;\n\tmemset(\u0026handler, 0, sizeof(handler));\n\tif (haclog_file_handler_init(\u0026handler, \"logs/hello.log\", \"w\") != 0) {\n\t\tfprintf(stderr, \"failed init file handler\");\n\t\texit(EXIT_FAILURE);\n\t}\n\thaclog_handler_set_level((haclog_handler_t *)\u0026handler, HACLOG_LEVEL_DEBUG);\n\thaclog_context_add_handler((haclog_handler_t *)\u0026handler);\n}\n```\n\n### rotate file handler\n```\nvoid add_file_rotate_handler()\n{\n\tstatic haclog_file_rotate_handler_t handler;\n\tmemset(\u0026handler, 0, sizeof(handler));\n\tif (haclog_file_rotate_handler_init(\u0026handler, \"logs/hello.rot.log\", 128 * 1024 * 1024, 5) != 0) {\n\t\tfprintf(stderr, \"failed init file handler\");\n\t\texit(EXIT_FAILURE);\n\t}\n\thaclog_handler_set_level((haclog_handler_t *)\u0026handler, HACLOG_LEVEL_DEBUG);\n\thaclog_context_add_handler((haclog_handler_t *)\u0026handler);\n}\n```\n\n### time rotate file handler\n```\nvoid add_file_time_rot_handler()\n{\n\tstatic haclog_file_time_rot_handler_t handler;\n\tmemset(\u0026handler, 0, sizeof(handler));\n\tif (haclog_file_time_rotate_handler_init( \u0026handler, \"logs/hello.time_rot.log\", HACLOG_TIME_ROTATE_UNIT_DAY, 2, 0) != 0) {\n\t\tfprintf(stderr, \"failed init file time rotate handler\");\n\t\texit(EXIT_FAILURE);\n\t}\n\thaclog_handler_set_level((haclog_handler_t *)\u0026handler, HACLOG_LEVEL_DEBUG);\n\thaclog_context_add_handler((haclog_handler_t *)\u0026handler);\n}\n```\n\n### Customize log format\nBy default, detailed log information will be printed in the following pattern:  \n`${level}|${UTC+0 datetime}|${file \u0026 line number}|${function}|${thread id}`  \n\nUser can Customize log meta format\n```\nint my_write_meta(struct haclog_handler *handler, haclog_meta_info_t *meta)\n{\n\tconst char *level = haclog_level_to_str(meta-\u003eloc-\u003elevel);\n\treturn handler-\u003ewritev(handler, \"%s|%llu.%lu \", level,\n\t\t\t\t\t\t   (unsigned long long)meta-\u003ets.tv_sec,\n\t\t\t\t\t\t   (unsigned long)meta-\u003ets.tv_nsec);\n}\n\n...\n\nhaclog_handler_set_fn_write_meta((haclog_handler_t *)\u0026handler, my_write_meta);\nhaclog_context_add_handler((haclog_handler_t *)\u0026handler);\n```\n\n### Set Bytes Buffer size\n```\nhaclog_context_set_bytes_buf_size(2 * 1024 * 1024);\n```\n\n### Set max length of one log line \n```\nhaclog_context_set_msg_buf_size(2048);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmugglewei%2Fhaclog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmugglewei%2Fhaclog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmugglewei%2Fhaclog/lists"}