{"id":18823149,"url":"https://github.com/mobius3/logtrace","last_synced_at":"2026-01-19T08:30:16.289Z","repository":{"id":15067358,"uuid":"17793640","full_name":"mobius3/logtrace","owner":"mobius3","description":"The logtrace logging library","archived":false,"fork":false,"pushed_at":"2014-04-12T20:34:08.000Z","size":192,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-12-30T04:20:06.611Z","etag":null,"topics":[],"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/mobius3.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}},"created_at":"2014-03-16T06:29:53.000Z","updated_at":"2019-12-29T00:34:52.000Z","dependencies_parsed_at":"2022-07-16T21:33:01.827Z","dependency_job_id":null,"html_url":"https://github.com/mobius3/logtrace","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobius3%2Flogtrace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobius3%2Flogtrace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobius3%2Flogtrace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobius3%2Flogtrace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mobius3","download_url":"https://codeload.github.com/mobius3/logtrace/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239758965,"owners_count":19692054,"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-11-08T00:52:56.427Z","updated_at":"2026-01-19T08:30:16.227Z","avatar_url":"https://github.com/mobius3.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"The logtrace logging library\n============================\n\n**logtrace** is a C++11 library for adding logging capabilities to your application. It features multiple verbosity levels, nested function tracing (indented information when entering or leaving a function) and inclusive and exclusive filtering. It also features Android [logcat] support :)\n\nIt was designed to be as unobtrusive as possible and to keep your code free of such `LOGLIBRARY_LOGMESSAGE_ERROR(\"hi?\")` macros. No explicit inicialization required.\n\nInstallation\n------------\nDrop logtrace.h and logtrace.cc into your project where your source files can see it. Compile and link logtrace.cc together with your source files.\n\nUsing\n-----\n\nPlace a `#include \"logtrace.h` wherever you want to use it.\n\nBy default, logging is **disabled** and all **logtrace** related calls will do nothing. To activate them, you'll need to define the `LOGTRACE` compile-time macro. You can do that by placing `#define LOGTRACE` *before* including the header, or you can pass that as a flag to your compiler (consult your compiler help to see how to do it).\n\nQuickstart\n----------\n\nTo log your stuff, create an instance of the `logtrace` class and use it to print messages, like this:\n\n\n\n    #define LOGTRACE\n    #include \"logtrace.h\"\n\n    int main() {\n        logtrace trace;\n        trace(\"This is an information message\");\n        trace.w(\"This is a warning message\");\n        trace.e(\"This is an error message\");\n        return 0;\n    }\n\n\nBecause the trace object was declared without parameters, its [log level](#log-levels) is *information* and its [module](#modules) is not set. The output is something like this:\n\n    E : This is an error message\n    \nEvery message that has a log level below the global level (which defaults to **error**) will not appear.\n\nBuilding the message\n----------\n\nEach message logging function supports as many parameters as you want. The **logtrace** class will pass them directly to the output stream (which defaults to [`cout`][1]), so you might want to write \"[output operators]\" for your objects if you intend to trace them.\n\nFor instance, you can have something as:\n\n    logtrace trace;\n    int roses = 0xff0000, violets = 0x0000ff;\n    trace.e(\"Roses are\", roses, \"violets are\", violets);\n\nOutput:\n\n    E : Roses are 16711680 violets are 255\n    \nModules\n-------\n\nYou can define **modules** for each trace object, so that later you can [filter](#filters) messages by them. To do that, simply place the module name when instantiating the **logtrace** class:\n\n    int main() {\n        logtrace trace(\"main\"); /* trace messages from the \"main\" module */\n        ...\n    }\n\nThis would change the [first example](#quickstart)'s output to:\n\n    E main: This is an error message\n    \nYou can change the module of the trace object anytime by calling its `module()` method:\n\n    trace.module(\"main\"); /* this object module is now \"main\" */\n\n\n\nLog levels\n----------\n\n**logtrace** has four log levels. From the least to most verbose (or from the most to least severe), these are:\n\n- *error*\n- *warning*\n- *information*\n- *call tracing*\n\nThe default **global** level is *error*, this means that only error messages will appear. You can change the global verbosity level of **logtrace** by using the following code:\n\n\n    logtrace::globalverb() = logtrace::error;       /* only error messages */\n    logtrace::globalverb() = logtrace::warning;     /* warning and error messages */\n    logtrace::globalverb() = logtrace::info;        /* information, warning and error messages */\n    logtrace::globalverb() = logtrace::maximum;     /* everything, including function tracing */\n\nWhen instantiating your trace object you can set its default log level:\n\n    logtrace trace(\"main\", logtrace::warning);\n    \nEvery message through this particular **logtrace** object will have the *warning* level, unless specified otherwise by using the `.i()`, `.w()` or `.e()` functions. If the global level is bigger than *warning*, all messages from this object will be shown.\n\n\nIf we changed the code in the [modules section](#modules) to have `logtrace::globalverb() = logtrace::warning;` before instantiating logtrace, its output would be:\n\n    W main: This is a warning message \n    E main: This is an error message \n\nAs you can see, log levels are incremental. The last level, `logtrace::maximum`, is very verbose and useful to trace function calls. When set, this would be the output of the above example:\n\n    [ In main\n      I main: This is an information message \n      W main: This is a warning message \n      E main: This is an error message \n    ] Leaving main\n    \n    \nThis is useful for recursive function calls and also to easily spot how deep in your code the funcion gets called. Consider:\n\n    #define LOGTRACE\n    #include \"logtrace.h\"\n    \n    void foo(int i);\n    void bar(int i) {\n      logtrace trace(\"bar\");\n      if (i == 0) trace(\"Recursion stop.\");\n      else foo(--i);\n    }\n    \n    void foo(int i) {\n      logtrace trace(\"foo\");\n      if (i == 0) trace(\"Recursion stop.\");\n      else bar(--i);\n    }\n    \n    int main() {\n        logtrace::globalverb() = logtrace::maximum;        \n        logtrace trace(\"main\");\n        foo(2);\n        return 0;\n    }\n\n\nThis is the output:\n\n    [ In main\n      [ In foo\n        [ In bar\n          [ In foo\n            I foo: Recursion stop. \n          ] Leaving foo\n        ] Leaving bar\n      ] Leaving foo\n    ] Leaving main\n    \n    \nFilters\n-------\n\nBesides changing the log level, you can set **logtrace** to print only messages from the modules you want from, using the exclusive and the inclusive filters. The inclusive filter will ignore everything except what its in there while the exclusive will print everything except for what it is in there.\n\nThese filters will make **logtrace** *completely* ignore what shouldn't be printed. This includes the tracing and error messages.\n\nTo set the ignore filter:\n```cpp\nlogtrace::ignore().insert(\"foo\"); /* will ignore messages from the 'foo' module */\n```\n\nThe output of the previous example when ignoring messages from the `foo` module would be like this:\n\n    [ In main\n      [ In bar\n      ] Leaving bar\n    ] Leaving main\n\n\nSimilarly, to set the inclusive filter:\n```cpp\nlogtrace::filter().insert(\"foo\"); /* will print only messages from the 'foo' module */\n```\n\nOutput:\n\n    [ In foo\n      [ In foo\n        I foo: Recursion stop. \n      ] Leaving foo\n    ] Leaving foo\n\nTrace messages and helper macros\n---------------------------------\n\nYou can also set a trace message when instantiating the logtrace object. It will be shown when entering and leaving the function, together with the module:\n\n    logtrace trace(\"module\", \"trace\");\n    \nWill show\n\n    [ In module: trace\n    ] Leaving module: trace\n\nMaking use of that feature, there are some helper macros that will declare a trace object for you and initialize it with a desired log level and will print the function name that they pertain to. These are\n\n- `modinfo(module)`\n- `modwarn(module)`\n- `moderr(module)`\n\nThey will all create an object named `trace` with the specified module string. The *trace* message will be the function name. Replacing the `logtrace trace(\"foo\")`, `logtrace trace(\"bar\")` and `logtrace trace(\"main\")` with the macro `modinfo()`, the output would be:\n\n    [ In main: int main()\n      [ In foo: void foo(int)\n        [ In bar: void bar(int)\n          [ In foo: void foo(int)\n            I foo: Recursion stop. \n          ] Leaving foo: void foo(int)\n        ] Leaving bar: void bar(int)\n      ] Leaving foo: void foo(int)\n    ] Leaving main: int main()\n    \n    \nOutput to a file\n----------------\n\nTo output all the messages to a file, use the following code before you start logging stuff:\n\n    logtrace::open(\"/path/to/log.txt\");\n    \nThe destination file will be truncated.\n    \nAndroid support\n---------------\n\nThis library implements a [`streambuf`][2] that makes `cout` redirect its output to Android's [logcat] log viewer. This is automatically set when you use **logtrace** for the first time. This **streambuf** is largely based on the answer for [this][Android streambuf] StackOverflow question.\n\n[1]: http://www.cplusplus.com/reference/iostream/cout/\n[2]: http://www.cplusplus.com/reference/streambuf/streambuf/\n[output operators]: http://www.parashift.com/c++-faq/output-operator.html\n[logcat]: http://developer.android.com/tools/help/logcat.html\n[Android streambuf]: http://stackoverflow.com/questions/8870174/is-stdcout-usable-in-android-ndk\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobius3%2Flogtrace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmobius3%2Flogtrace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobius3%2Flogtrace/lists"}