{"id":13439884,"url":"https://github.com/square/logcat","last_synced_at":"2025-06-13T01:39:22.170Z","repository":{"id":37208355,"uuid":"407881610","full_name":"square/logcat","owner":"square","description":"I CAN HAZ LOGZ?","archived":false,"fork":false,"pushed_at":"2023-11-13T15:06:23.000Z","size":944,"stargazers_count":895,"open_issues_count":17,"forks_count":21,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-10-28T02:17:56.037Z","etag":null,"topics":["android","cats","logging"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/square.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-09-18T14:25:16.000Z","updated_at":"2024-10-16T20:37:59.000Z","dependencies_parsed_at":"2022-07-12T03:46:25.027Z","dependency_job_id":"98e83e6c-b339-43be-82ea-fc754debe98f","html_url":"https://github.com/square/logcat","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Flogcat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Flogcat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Flogcat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Flogcat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/square","download_url":"https://codeload.github.com/square/logcat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244585669,"owners_count":20476773,"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":["android","cats","logging"],"created_at":"2024-07-31T03:01:17.902Z","updated_at":"2025-06-13T01:39:22.124Z","avatar_url":"https://github.com/square.png","language":"Kotlin","funding_links":[],"categories":["HarmonyOS","Kotlin"],"sub_categories":["Windows Manager"],"readme":"# Square Logcat\n\n```kotlin\nlogcat { \"I CAN HAZ LOGZ?\" }\n```\n\nA tiny Kotlin API for cheap logging on top of Android's normal `Log` class.\n\n## Table of contents\n\n* [Setup](#setup)\n* [Usage](#usage)\n* [Motivations](#motivations)\n* [License](#license)\n\n![logo_512.png](assets/logo_512.png)\n\n_This fantastic logo is brought to you by [@rjrjr](https://github.com/rjrjr)._\n\n## Setup\n\nAdd the `logcat` dependency to your library or app's `build.gradle` file:\n\n```gradle\ndependencies {\n  implementation 'com.squareup.logcat:logcat:0.2.3'\n}\n```\n\nInstall `AndroidLogcatLogger` in `Application.onCreate()`:\n\n```kotlin\nimport android.app.Application\nimport logcat.AndroidLogcatLogger\nimport logcat.LogPriority.VERBOSE\n\nclass ExampleApplication : Application() {\n  override fun onCreate() {\n    super.onCreate()\n    // Log all priorities in debug builds, no-op in release builds.\n    AndroidLogcatLogger.installOnDebuggableApp(this, minPriority = VERBOSE)\n  }\n}\n```\n\n## Usage\n\nThe `logcat()` function has 3 parameters: an optional priority, an optional tag, and a required\nstring producing lambda. The lambda is only evaluated if a logger is installed and the logger deems\nthe priority loggable.\n\nThe priority defaults to `LogPriority.DEBUG`.\n\nThe tag defaults to the class name of the log call site, without any extra runtime cost. This works\nbecause `logcat()` is an inlined extension function of `Any` and has access to `this` from which\nit can extract the class name. If logging from a standalone function which has no `this`, use the\n`logcat` overload which requires a tag parameter.\n\nThe `logcat()` function does not take a `Throwable` parameter. Instead, the library provides\na Throwable extension function: `Throwable.asLog()` which returns a loggable string.\n\n```kotlin\nimport logcat.LogPriority.INFO\nimport logcat.asLog\nimport logcat.logcat\n\nclass MouseController {\n\n  fun play() {\n    val state = \"CHEEZBURGER\"\n    logcat { \"I CAN HAZ $state?\" }\n    // logcat output: D/MouseController: I CAN HAZ CHEEZBURGER?\n\n    logcat(INFO) { \"DID U ASK 4 MOAR INFO?\" }\n    // logcat output: I/MouseController: DID U ASK 4 MOAR INFO?\n\n    logcat { exception.asLog() }\n    // logcat output: D/MouseController: java.lang.RuntimeException: FYLEZ KERUPTED\n    //                        at sample.MouseController.play(MouseController.kt:22)\n    //                        ...\n\n    logcat(\"Lolcat\") { \"OH HI\" }\n    // logcat output: D/Lolcat: OH HI\n  }\n}\n```\n\n## Motivations\n\nWe built this small library to fit the specific needs of the Square\n[Point of Sale](https://squareup.com/us/en/point-of-sale) application. We used\n[Timber](https://github.com/JakeWharton/timber) heavily before that, and love the simplicity of its\nAPI and the ability of its `DebugTree` to automatically figure out from which class it's being\ncalled from and use that class name as its tag. Here are our motivations for replacing it with\n`logcat()` in the Square Point of Sale:\n\n- Kotlin support for string interpolation is really nice. We love to use that for logs!\nUnfortunately that can be costly and a waste of good CPU if logging is disabled anyway. By using\nan inlined string producing lambda, `logcat()` supports string interpolation without any\nperformance cost when logging is disabled.\n- Timber's `DebugTree` captures the calling class name as a tag by creating a stacktrace, which can\nbe expensive. By making `logcat()` an extension function of `Any`, we can call `this::class.java`\nand get the calling context without creating a stacktrace.\n- The current implementation uses the outer most simple class name as the tag, i.e. the string\nbetween on the last `.` and the first `$`. That might not always be what you want. Also, when\nlogging from an abstract class the tag will be the name of the subclass at runtime. We've found\nthese limitations to be totally fine with us so far.\n- Most of the time, our developers just want to \"send something to logcat\" without even thinking\nabout priority. `logcat()` picks \"debug\" as the right default to provide more consistency across\na large codebase. Making the priority a parameter also means only one method to learn, and you\ndon't have to learn / think about priorities prior to writing a log. This becomes especially\nimportant when there are several parameters requiring overloads (e.g. in Timber (6 priorities + 1\ngeneric log method) * 3 overloads = 21 methods to choose from).\n- The lack of throwable parameter is also intentional. It just creates more overloads and confusion\n(e.g. \"what's the param order?\"), when really logs are about strings and all you need is an easy\nway to turn a throwable into a loggable string. Hence `Throwable.asLog()`.\n- The name `logcat()` is intentionally boring and identical to the Android command line tool. This\nmakes it easy to remember and developers know exactly what this does, i.e. log to the local device.\nOne could setup a custom logger that send logs remotely in release builds, however we do not\nrecommend doing so: in our experience, remote logs should be distinct in code from local logs and\nclearly identified as such, because the volume and performance impact should be very distinct.\n- The API for installing a logger is separated out from the API to log, as these operations occur\nin very distinct contexts.\n\n## License\n\n\u003cpre\u003e\nCopyright 2021 Square Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\u003c/pre\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquare%2Flogcat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquare%2Flogcat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquare%2Flogcat/lists"}