{"id":25667262,"url":"https://github.com/marcpage/yalo","last_synced_at":"2026-06-11T01:31:29.910Z","repository":{"id":278966658,"uuid":"936933974","full_name":"marcpage/yalo","owner":"marcpage","description":"Yet Another Logger C++ light-weight logging","archived":false,"fork":false,"pushed_at":"2025-03-03T07:46:23.000Z","size":45,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-17T01:21:33.649Z","etag":null,"topics":["c-plus-plus","c-plus-plus-11","cplusplus-11","cpp","cross-platform","header-only","logger","logging","logging-library"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcpage.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-22T00:35:16.000Z","updated_at":"2025-03-03T07:46:26.000Z","dependencies_parsed_at":"2025-02-22T21:26:01.427Z","dependency_job_id":"bcff5d3c-74d2-4927-8bbe-79a23819a327","html_url":"https://github.com/marcpage/yalo","commit_stats":null,"previous_names":["marcpage/yalo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/marcpage/yalo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcpage%2Fyalo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcpage%2Fyalo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcpage%2Fyalo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcpage%2Fyalo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcpage","download_url":"https://codeload.github.com/marcpage/yalo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcpage%2Fyalo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34178819,"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-10T02:00:07.152Z","response_time":89,"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":["c-plus-plus","c-plus-plus-11","cplusplus-11","cpp","cross-platform","header-only","logger","logging","logging-library"],"created_at":"2025-02-24T09:28:59.690Z","updated_at":"2026-06-11T01:31:29.892Z","avatar_url":"https://github.com/marcpage.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# yalo\n\n![status sheild](https://img.shields.io/static/v1?label=test+coverage\u0026message=87%\u0026color=active\u0026style=plastic)\n![GitHub](https://img.shields.io/github/license/marcpage/yalo?style=plastic)\n[![commit sheild](https://img.shields.io/github/last-commit/marcpage/yalo?style=plastic)](https://github.com/marcpage/yalo/commits)\n[![activity sheild](https://img.shields.io/github/commit-activity/m/marcpage/yalo?style=plastic)](https://github.com/marcpage/yalo/commits)\n![GitHub top language](https://img.shields.io/github/languages/top/marcpage/yalo?style=plastic)\n[![size sheild](https://img.shields.io/github/languages/code-size/marcpage/yalo?style=plastic)](https://github.com/marcpage/yalo)\n[![issues sheild](https://img.shields.io/github/issues-raw/marcpage/yalo?style=plastic)](https://github.com/marcpage/yalo/issues)\n[![follow sheild](https://img.shields.io/github/followers/marcpage?label=Follow\u0026style=social)](https://github.com/marcpage?tab=followers)\n[![watch sheild](https://img.shields.io/github/watchers/marcpage/yalo?label=Watch\u0026style=social)](https://github.com/marcpage/yalo/watchers)\n\nYet Another Logger: C++ light-weight logger\n\n## Features\n\n- Single header file, less than 1,000 lines of code\n- Supports C++11 and later\n- Supports Linux, macOS, and Windows\n- Threadsafe (and thread identification)\n- Minimal coding to log\n- Logs timestamp, thread, [level](#logging-levels), file, line number, function, condition\n- Logs to `stdout`, `stderr`, and/or files\n- Customize to log to other destinations\n- Customize to change the format of the logging output\n- Can create/update a [file to change logging settings while code is running](#changing-log-levels-at-runtime)\n- Can automaticaly log all `if`, `while`, and `switch` statements in `Trace` mode\n- Can [set logging level per file or group of files](#setlevel)\n- Over 80% unit test code coverage\n\n## Logging Levels\n\n| Constant | Call | Description |\n|---|---|---|\n| yalo::Fatal | lFatal | Always log and call abort() |\n| yalo::Fatal | lFatalIf(condition) | If condition is true, log and call abort() |\n| yalo::Log | lLog | Information that should always be in the log (version, settings, etc) |\n| yalo::Error | lError | An error occurred (default logging level) |\n| yalo::Error | lErrorIf(condition) | `condition` is the error condition and will log if true(default logging level) |\n| yalo::Warning | lWarn | Warn about potential problems |\n| yalo::Warning | lWarnIf(condition) | `condition` is a potential problem if true |\n| yalo::Info | lInfo | Log general information |\n| yalo::Debug | lDebug | Log information helpful for debugging |\n| yalo::Verbose | lVerbose | Log an excessive amount of information for deeper debugging |\n| yalo::Trace | lTrace | Log execution, including every `if`, `while`, and `switch` |\n\n### Trace if, while, and switch\n\nBy default, every `if`, `while`, and `switch` will be available in `yalo::Trace` mode.\nThis adds a small amount of code to every `if`, `while` iteration, and `switch`.\nWhile this code is small, it may have a performance impact.\nTo disable this tracing ability, you can define `DISABLE_YALO_TRACE`.\n\n### Example logging code\n\n```C++\n    lLog \u003c\u003c \"Program version\" \u003c\u003c version_string;\n    lErr \u003c\u003c \"We're all going to die!\";\n    lErrIf(file == nullptr) \u003c\u003c \"crash eminent!\";\n    lWarn \u003c\u003c \"Warning!\";\n    lWarnIf(size \u003e 5) \u003c\u003c \"We should work but this is kind of big\" \u003c\u003c size;\n    lInfo \u003c\u003c \"How did we get here?\";\n    lDebug \u003c\u003c \"iteration #\" \u003c\u003c iteration \u003c\u003c \"size = \" \u003c\u003c size;\n    lVerbose \u003c\u003c \"Checking if we should move forward\";\n    lTrace \u003c\u003c \"Here\";\n    if (x == 5 \u0026\u0026 y == 7) {...}\n```\n\n### Example log\n\nThe log can output the following information:\n\n- Timestamp (local or GMT)\n- Thread index (index of the order in which the threads logged)\n- Log [level](#logging-levels)\n- Source file\n- Source line number\n- Function or method\n- Conditional that triggered the logging\n- The log message\n\n```html\n[2025-02-23 02:52:22.912 (Sun)][0][LOG] New Settings File: bin/testCommandFile.txt\n[2025-02-23 02:52:22.912 (Sun)][0][LOG] Resetting format to default GMT\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] Resetting format to default\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] Adding sink to bin/testCommandFile.log\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] resetLevels to 0\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] Turned padding on\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] Turned padding off\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] Set level #1 pattern = ''\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] Set level #4 pattern = 'test_yalo.cpp'\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][DBG][src/tests/test_yalo.cpp:495][testCommandFile] testing\n[2025-02-22 20:52:22.912 -0600 (Sat)][0][LOG] New Settings File: bin/nonexistant/path/testCommandFile.txt\n[2025-02-23 02:52:22.912 (Sun)][0][WRN][src/tests/test_yalo.cpp:523][testConditionals][value1 \u003e 2] too big\n[2025-02-23 02:52:22.912 (Sun)][0][ERR][src/tests/test_yalo.cpp:524][testConditionals][value1 \u003c 10] too small\n[2025-02-23 02:52:22.913 (Sun)][0][LOG] New Settings File: bin/nonexistant/path/testCommandFile.txt\n```\n\n## Changing log levels at Runtime\n\nIn the code you can specify a path to a file to watch for logging settings.\nYou can do this by calling `yalo::Logger::setSettingsFile({path}, {secondsBetweenChecks});`\n\nHere is an example of the file:\n\n```\nsetLevel: Error\nsetLevel: Trace=main.cpp\naddSinkStdErr\naddSink:debugging.txt\n```\n\nYou can have the following commands in the file:\n\n- [addSink](#addsink)\n- [addSinkStdErr](#addsinkstderr)\n- [addSinkStdOut](#addsinkstdout)\n- [clearSinks](#clearsinks)\n- [noPad](#nopad)\n- [pad](#pad)\n- [resetLevels](#resetlevels)\n- [setFormatDefault](#setformatdefault)\n- [setFormatDefaultGMT](#setformatdefaultgmt)\n- [setLevel](#setlevel) (globally and for specific files)\n\n### addSink\n\nSame as calling `Logger::addSink(std::unique_ptr\u003cFileSink\u003e(new FileSink({path})));`\n\n```\naddSink:{path}\n```\n\nStarts logging to the given path.\n\n### addSinkStdErr\n\nSame as calling `Logger::addSink(std::unique_ptr\u003cStdErrSink\u003e(new StdErrSink()));`\n\n```\naddSinkStdErr\n```\n\nStarts logging to `stderr`.\n\n*Note*: If you are already logging to `stderr` or specify this command more than once you will see duplicate lines.\n\n### addSinkStdOut\n\nSame as calling `Logger::addSink(std::unique_ptr\u003cStdOutSink\u003e(new StdOutSink()));`\n\n```\naddSinkStdOut\n```\n\nStarts logging to `stdout`.\n\n*Note*: If you are already logging to `stdout` or specify this command more than once you will see duplicate lines.\n\n### clearSinks\n\nSame as calling `Logger::clearSinks();`\n\n```\nclearSinks\n```\n\nRemoves all current logging sinks.\n\n*Note*: If this is not immedeately followed by `addSinkStdOut`, `addSinkStdErr`, or `addSink` then `addSinkStdErr` will automatically happen.\n\n### noPad\n\nSame as calling `Logger::setInserterSpacing(InserterAsIs);`\n\n```\nnoPad\n```\n\nWhen log streaming, no extra spacing will be inserted between inserts.\n\n```\nlLog \u003c\u003c \"test\" \u003c\u003c 5 \u003c\u003c \"more\";\n```\n\nwill result in logging:\n\n```\ntest5more\n```\n\n### pad\n\nSame as calling `Logger::setInserterSpacing(InserterPad);`\n\n```\npad\n```\n\nWhen log streaming, an extra space will be inserted between inserts.\n\n```\nlLog \u003c\u003c \"test\" \u003c\u003c 5 \u003c\u003c \"more\";\n```\n\nwill result in logging:\n\n```\ntest 5 more\n```\n\n### resetLevels\n\nSame as calling `Logger::resetLevels(_fromString({level}));`\n\n```\nresetLevels:{level}\n```\n\nClears all file pattern files and sets all logging to [{level}](#logging-levels).\n\n### setFormatDefault\n\nSame as calling `Logger::setFormat(std::unique_ptr\u003cDefaultFormatter\u003e(new DefaultFormatter()));`\n\n```\nsetFormatDefault\n```\n\nReset the log formatter back to the default, using local time.\n\n### setFormatDefaultGMT\n\nSame as calling `Logger::setFormat(std::unique_ptr\u003cDefaultFormatter\u003e(new DefaultFormatter(DefaultFormatter::GMT)));`\n\n```\nsetFormatDefaultGMT\n```\n\nReset the log formatter back to the default, using GMT time.\n\n### setLevel\n\nSame as calling `Logger::setLevel({level}, {pattern});`\n```\nsetLevel:{level}\nsetLevel:{level}={pattern}\n```\n\nThe first entry will set the default global [{level}](#logging-levels).\nThe second entry will set the [{level}](#logging-levels) for the given [file pattern](#file-patterns).\n\n#### File Patterns\n\nYou can specify a file matching pattern to change the logging level per file or group of files.\nThe pattern consists of case-sensitive substrings to look for in the file, separated by semicolon (`;`).\nIf a pattern begins with a minus (`-`) then it will not match that pattern.\nThe evaluation walks through all the patterns with positive patterns being ORed in and negative patterns removing files.\n\n##### File pattern example\n\n```\nsrc/;-src/include/;-main.cpp\n```\n\nThis is interpreted as: files that contain `src/` in them, but do not include `src/include` and do not include `main.cpp`.\n\nBasically take your filename and walk through the pattern and add it if at matches a positive and remove it when it matches a negative.\n\n```\nsrc/;-src/include/;.cpp\n```\n\nThis example shows all files under `src/`, but not files in `src/include/`, but do include `.cpp` files (including those in `src/include/`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcpage%2Fyalo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcpage%2Fyalo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcpage%2Fyalo/lists"}