{"id":15672402,"url":"https://github.com/bonedaddy/ulog","last_synced_at":"2025-07-06T12:02:58.819Z","repository":{"id":119062312,"uuid":"286341223","full_name":"bonedaddy/ulog","owner":"bonedaddy","description":"ulog (uber log) is a lightweight and threadsafe logger in C that provides color coded output, as well as the ability to send logs to a file.","archived":false,"fork":false,"pushed_at":"2024-12-05T04:51:54.000Z","size":899,"stargazers_count":17,"open_issues_count":5,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-31T03:03:32.814Z","etag":null,"topics":["c","clog","clogger","logging","threadsafe","ulog","valgrind"],"latest_commit_sha":null,"homepage":"https://ulog.bonedaddy.io","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bonedaddy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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-08-10T00:34:58.000Z","updated_at":"2024-12-05T04:55:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"3b0eebc2-3cae-4a5e-861c-38c7dfbcaf2e","html_url":"https://github.com/bonedaddy/ulog","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bonedaddy%2Fulog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bonedaddy%2Fulog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bonedaddy%2Fulog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bonedaddy%2Fulog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bonedaddy","download_url":"https://codeload.github.com/bonedaddy/ulog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252770010,"owners_count":21801463,"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","clog","clogger","logging","threadsafe","ulog","valgrind"],"created_at":"2024-10-03T15:25:30.677Z","updated_at":"2025-05-06T21:22:27.207Z","avatar_url":"https://github.com/bonedaddy.png","language":"C","readme":"# ulog\n\n![](./example.png)\n\n`ulog` (uber log) is a lightweight and threadsafe logging library written in C, with support for C++. It features color coded output, with the ability to send logs to stdout and a file. File and line information indicating what fired the log is also included. It has INFO, WARN, ERROR, and DEBUG log levels, and is thoroughly tested with cmocka and valgrind. \n\nIf not using debug logging then any DEBUG level log calls are silently skipped. The logger is threadsafe in that multiple threads can't log at the same time. In practice there is very little lock contention and in all honesty you will probably never have to worry about it.\n\nIn terms of memory usage, the only memory allocations conducted by this library are when initializing the logger. During actual logging there is no memory allocations whatsoever, as we use stack allocated variables. In practice logger initialization consumes arounds 7.4 KiB of memory, while regular logger usage general consumes no more than 3 -\u003e 3.4 KiB of memory at any one time.\n\n**Please be aware that after calling `clear_thread_logger` or `clear_file_logger` using the logger results in undefined behavior, likely a panic causing the program to exit. Having one or more threads initiate a log invocation while concurrently calling `clear_thread_logger` or `clear_file_logger` results in undefined behavior. When clearing the logger you must be certain no other threads will attempt to use the logger.**\n\n# features\n\n* C/C++ support\n* lightweight (3 -\u003e 3.4 KiB memory consumption)\n* threadsafe\n* color coded logs\n* stdout and file descriptor logging\n* file and line number that emitted the log included\n\n# why another logging library?\n\nI wanted a simple logging library that didnt leak memory, was well tested, and capable of color coded output. All logging libraries I found were complex code bases, leaked memory, and relied on global variables. Because of that, and as a way to better learn C development `ulog` was born.\n\nInterested in reading more about how `ulog` was born? [I published a blog post detailing the creation](https://bonedaddy.io/blog/misc/ulog_lightweight_threadsafe/).\n\n# versioning\n\nThe library follows the semver versioning scheme. Additionally a `version.h` header file has the current release version listed as a macro.\n\n# installation\n\n## manual (broke)\n\nCopy and paste the `logger.h`, `colors.h`, `version.h`, `logger.c`, and `colors.c` files into whatever project you are working on. You will need to make sure that you have pthreads available to link with as the logger library has a pthreads dependency.\n\n## clib (woke)\n\nIf you use the [clib package manager](https://github.com/clibs/clib) then you can install `ulog` into your project with a single command:\n\n```shell\n$\u003e clib install bonedaddy/ulog\n```\n\n# testing\n\nBefore testing you'll need to compile the code, for which you have two options\n\nRelease mode\n\n```shell\n$\u003e make\n```\n\nDebug mode\n\n```shell\n$\u003e make build-debug\n```\n\nRunning either of the following two commands will build a test executable `logger-test` within the `build` folder. You can either invoke this manually or use `ctest`.\n\nRegular unit testing:\n\n```shell\n$\u003e ctest\n```\n\nValgrind dynamic analysis and unit testing:\n\n```shell\n$\u003e ctest -T memcheck\n```\n\n# usage\n\nThe primary method of interacting with ulog is by using macros. The macros allow you to emit logs at various levels, minimizing the amount of typing required to do so. There are a total of four macros that can be used, the base macros are denoted in the form of `LOG_\u003cLEVEL\u003e` and `LOGF_\u003cLEVEL\u003e` which provide the capabilities to emit logs to standard out. The `LOG_` macros can be used to emit a log message as is, that is to say you provide a single message to emit, while the `LOGF_` macros can be used to emit a log message formatted according to the printf formatting rules leveraging variadic arguments. \n\nThere are two additional macros that mimic `LOG_\u003cLEVEL\u003e` and `LOGF_\u003cLEVEL\u003e` however they will also log to a given file, while also logging to stdout. They are `fLOG_\u003cLEVEL\u003e` and `fLOG_\u003cLEVEL\u003e`. The main difference between these, other than the fact that file logging capabilities are provided, is that the `LOG_\u003cLEVEL\u003e` and `LOGF_\u003cLEVEL\u003e` macros take in an instance of `thread_logger` while the `fLOG_\u003cLEVEL\u003e` and `fLOGF_\u003cLEVEL\u003e` macros take in an instance of `file_logger`.\n\nBelow you'll find examples that showcase how to generate the logs that were captured in the screenshot displayed at the beginning of this readme.\n\n## stdout only\n\n```C\n#include \u003cstdbool.H\u003e\n#include \"logger.h\"\n\nthread_logger *thl = new_thread_logger(true);\n\nLOG_INFO(thl, \"this is an info log\");\nLOG_WARN(thl, \"this is a warn log\");\nLOG_ERROR(thl, \"this is an error log\");\nLOG_DEBUG(thl, \"this is a debug log\");\n\n// the LOGF_ prefixed functions can be used for printf styled output\nLOGF_INFO(thl, \"this is a %s style info log\", \"printf\");\nLOGF_WARN(thl, \"this is a %s style warn log\", \"printf\");\nLOGF_ERROR(thl, \"this is a %s style error log\", \"printf\");\nLOGF_DEBUG(thl, \"this is a %s style debug log\", \"printf\");\n\n// free up memory when you no longer need the logger\n// note: after this returns thl is no logner safe to use\nclear_thread_logger(thl);\n```\n\n## file and stdout\n\n```C\n#include \u003cstdbool.h\u003e\n#include \"logger.h\"\n\n\nfile_logger *fhl = new_file_logger(\"testfile.log\", true);\n\nfLOG_INFO(fhl, \"this is an info log\");\nfLOG_WARN(fhl, \"this is a warn log\");\nfLOG_ERROR(fhl, \"this is an error log\");\nfLOG_DEBUG(fhl, \"this is a debug log\");\n\nfLOGF_INFO(fhl, \"this is a %s style info log\", \"printf\");\nfLOGF_WARN(fhl, \"this is a %s style warn log\", \"printf\");\nfLOGF_ERROR(fhl, \"this is a %s style error log\", \"printf\");\nfLOGF_DEBUG(fhl, \"this is a %s style debug log\", \"printf\");\n\n// if you dont want to log to a file you will want to use the LOG_ and LOGF_ macros\nLOG_INFO(fhl-\u003ethl, \"this will only log to stdout\");\nLOGF_INFO(fhl-\u003ethl, \"this will only log to %s\", \"stdout\");\n\nclear_file_logger(fhl);\n```\n\n# license\n\nAGPLv3 licensed, although if you want commercial license under MIT that can be aranged for a small fee.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbonedaddy%2Fulog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbonedaddy%2Fulog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbonedaddy%2Fulog/lists"}