{"id":18808578,"url":"https://github.com/getstream/stream-log","last_synced_at":"2025-10-24T14:42:02.352Z","repository":{"id":64293962,"uuid":"571624075","full_name":"GetStream/stream-log","owner":"GetStream","description":"🛥 Stream Log is a lightweight and extensible logger library for Kotlin Multiplatform.","archived":false,"fork":false,"pushed_at":"2025-03-27T07:26:53.000Z","size":581,"stargazers_count":142,"open_issues_count":1,"forks_count":7,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-03-28T16:09:35.340Z","etag":null,"topics":["android","getstream","kotlin","logger","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/GetStream.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2022-11-28T14:31:58.000Z","updated_at":"2025-03-06T11:30:01.000Z","dependencies_parsed_at":"2024-11-15T00:02:35.785Z","dependency_job_id":"62815dc5-404f-48e9-8bdb-ae673d0739dc","html_url":"https://github.com/GetStream/stream-log","commit_stats":{"total_commits":80,"total_committers":3,"mean_commits":"26.666666666666668","dds":"0.26249999999999996","last_synced_commit":"0175ec9eb8749b0d203bb1091558dc15c01539be"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-log","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-log/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-log/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetStream%2Fstream-log/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GetStream","download_url":"https://codeload.github.com/GetStream/stream-log/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247217183,"owners_count":20903009,"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","getstream","kotlin","logger","logging"],"created_at":"2024-11-07T23:13:24.310Z","updated_at":"2025-10-24T14:41:56.882Z","avatar_url":"https://github.com/GetStream.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eStream Log\u003c/h1\u003e\u003c/br\u003e\n\n\u003cp align=\"center\"\u003e\n🛥 Stream Log is a lightweight and extensible logger library for Kotlin Multiplatform.\n\u003c/p\u003e\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://opensource.org/licenses/Apache-2.0\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://android-arsenal.com/api?level=21\"\u003e\u003cimg alt=\"API\" src=\"https://img.shields.io/badge/API-21%2B-brightgreen.svg?style=flat\"/\u003e\u003c/a\u003e\n \u003ca href=\"https://github.com/GetStream/stream-log/actions/workflows/build.yml\"\u003e\u003cimg alt=\"Build Status\" src=\"https://github.com/GetStream/stream-log/actions/workflows/build.yml/badge.svg\"/\u003e\u003c/a\u003e\n \u003ca href=\"https://androidweekly.net/issues/issue-548\"\u003e\u003cimg alt=\"Android Weekly\" src=\"https://skydoves.github.io/badges/android-weekly.svg\"/\u003e\u003c/a\u003e\n \u003ca href=\"https://us12.campaign-archive.com/?u=f39692e245b94f7fb693b6d82\u0026id=dae9760573\"\u003e\u003cimg alt=\"Kotlin Weekly\" src=\"https://skydoves.github.io/badges/kotlin-weekly.svg\"/\u003e\u003c/a\u003e\n \u003ca href=\"https://getstream.io?utm_source=Github\u0026utm_medium=Github_Repo_Content_Ad\u0026utm_content=Developer\u0026utm_campaign=Github_Dec2022_StreamLog\u0026utm_term=DevRelOss\"\u003e\u003cimg src=\"https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/HayesGordon/e7f3c4587859c17f3e593fd3ff5b13f4/raw/11d9d9385c9f34374ede25f6471dc743b977a914/badge.json\" alt=\"Stream Feeds\"\u003e\u003c/a\u003e\n\u003c/p\u003e\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://getstream.io/chat/sdk/android/\"\u003e\u003cimg width=\"210px\" alt=\"Logo\" src=\"https://user-images.githubusercontent.com/24237865/205788244-57f7200c-7ed6-456a-927e-2594e3b311bf.png\"/\u003e\u003c/a\u003e \u003cbr\u003e\n\u003c/p\u003e\n\n## Why Stream Log?\n\n**Stream Log** originated from [stream-chat-android](https://github.com/getStream/stream-chat-android), and it has already been verified by delivering to billions of global end-users across thousands of different apps. It's simple and easy to use. You can also record and extract the runtime log messages into an external `.txt` file and utilize it to trace your log messages.\n\n\u003cimg align=\"right\" width=\"90px\" src=\"https://user-images.githubusercontent.com/24237865/178630165-76855349-ac04-4474-8bcf-8eb5f8c41095.png\"/\u003e\n\n## Stream Log\n\n**Stream Log** is a lightweight logger and a pure Kotlin module to utilize this library on your Kotlin Multiplatform projects. It supports Android, iOS, macOS, Jvm\n\n[![Maven Central](https://img.shields.io/maven-central/v/io.getstream/stream-log.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.getstream%22%20AND%20a:%22stream-log%22)\n\nAdd the dependency below into your **module**'s `build.gradle` file:\n\n```gradle\ndependencies {\n    implementation(\"io.getstream:stream-log:$version\")\n}\n```\n\nIf you're targeting on Kotlin Multiplatform, add the dependency below to your module's `build.gradle.kts` file:\n\n```kotlin\nsourceSets {\n    val commonMain by getting {\n        dependencies {\n            implementation(\"io.getstream:stream-log:$version\")\n        }\n    }\n}\n```\n\n### StreamLog\n\n`StreamLog` is a primary log manager, which allows you to install your loggers and print log messages. First, you need to install a `StreamLogger` on `StreamLog`. StreamLog offers a default platform-specific logger that you can install right away by using the code below:\n\n```kotlin\nKotlinStreamLogger.installPlatformStreamLogger(minPriority = Priority.DEBUG, maxTagLength = 23)\n```\n\nNow, you can print log messages simply like the below:\n\n```kotlin\nstreamLog { \"This is a log messages\" }\nstreamLog(priority = Priority.INFO, tag = \"Tag\") { \"This is a log messages\" }\nStreamLog.d(tag = \"Tag\") { \"This is a log message\" }\n```\n\nThen you will get the log messages below:\n\n```diff\n+  D  2022-12-02 15:42:49'044 (main:2) [D/MessageRepository]: This is a log message!\n+  I  2022-12-02 15:42:49'044 (main:2) [I/Tag]: This is a log message!\n+  D  2022-12-02 15:42:49'044 (main:2) [D/Tag]: This is a log message!\n```\n\nAlso, you can get the logger, which is installed on `StreamLog` like the below:\n\n```kotlin\nval logger = StreamLog.getLogger(\"Tag\")\nlogger.d { \"This is a log message\" }\n\n// Getting a tagged logger lazily.\nval logger by taggedLogger()\nval logger by taggedLogger(tag = \"Tag\")\n```\n\n\u003e**Note**: If you don't specify the `tag` parameter, the tag value will be a class name that is logging currently.\n\n\u003cimg align=\"right\" width=\"140px\" src=\"https://user-images.githubusercontent.com/24237865/205479526-5fa0b5f0-22df-4f02-ac0e-7a7a3e050cdb.png\"/\u003e\n\n### Platform-Specific Stream Logger\n\nStreamLog provides differnt stream logger depending on the platform below:\n\n- Android: `AndroidStreamLogger`\n- iOS/macOS: `AppleStreamLogger`\n- Jvm: `JvmStreamLogger`\n\nYou can install those logger like the example below:\n\n```kotlin\nStreamLog.install(AndroidStreamLogger()) // AppleStreamLogger() or JvmStreamLogger() depending on your platform.\n```\n\nIf you want to use Stream Log on your Android project, you can follow the guidelines. First, you need to install a logger for Android with `AndroidStreamLogger` like the below:\n\n```kotlin\nclass App : Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n\n        // install AndroidStreamLogger.\n        AndroidStreamLogger.installOnDebuggableApp(this)\n        \n        // change the log validator as your taste.\n        StreamLog.setValidator { priority, _ -\u003e priority.level \u003e= Priority.VERBOSE.level }\n    }\n}\n```\n\n\u003e**Note**: We'd recommend you install the logger only once in your application class.\n\nNow, you can print log messages simply like the below:\n\n```kotlin\nstreamLog { \"This is a log messages\" }\nstreamLog(priority = Priority.INFO, tag = \"Tag\") { \"This is a log messages\" }\nStreamLog.d(tag = \"Tag\") { \"This is a log message\" }\n```\n\nThen you will get the log messages below:\n\n```diff\n+  D  2022-12-02 15:42:49'044 (main:2) [D/MessageRepository]: This is a log message!\n+  I  2022-12-02 15:42:49'044 (main:2) [I/Tag]: This is a log message!\n+  D  2022-12-02 15:42:49'044 (main:2) [D/Tag]: This is a log message!\n```\n\nYou also can get the logger, which is installed on `StreamLog` like the below:\n\n```kotlin\nval logger = StreamLog.getLogger(\"Tag\")\nlogger.d { \"This is a log message\" }\n\n// Getting a tagged logger lazily.\nval logger by taggedLogger()\nval logger by taggedLogger(tag = \"Tag\")\n```\n\n\u003e**Note**: If you don't specify the `tag` parameter, the tag value will be a class name that is logging currently. In Jetpack Compose, the tag will be the scope's name of Composable functions.\n\n### KotlinStreamLogger\n\n`KotlinStreamLogger` is the low-level logger abstract class of that can be installed/uninstalled on `StreamLog`. So you can simply create your own stream logger and install it like the code below:\n\n```kotlin\npublic class MyStreamLogger(\n  private val maxTagLength: Int = DEFAULT_MAX_TAG_LENGTH,\n) : KotlinStreamLogger(), StreamLogger {\n\n  public override val now: () -\u003e LocalDateTime =\n    { Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) }\n\n  override fun log(priority: Priority, tag: String, message: String, throwable: Throwable?) {\n    val now = now.invoke()\n    val jvmTag = tag.takeIf { it.length \u003e maxTagLength }\n      ?.substring(0, maxTagLength)\n      ?: tag\n    val thread = platformThread.run { \"$name:$id\" }\n    val composed = \"$now ($thread) [${priority.stringify()}/$jvmTag]: $message\"\n    val finalMessage = throwable?.let {\n      \"$composed\\n${it.stringify()}\"\n    } ?: composed\n    when (priority) {\n      Priority.ERROR, Priority.ASSERT -\u003e printlnError(finalMessage)\n      else -\u003e println(finalMessage)\n    }\n  }\n\n  override fun install(minPriority: Priority, maxTagLength: Int) {}\n}\n\n// install `KotlinStreamLogger`. You only need to do this once.\nStreamLog.install(MyStreamLogger())\n\n// change the log validator as your taste. \nStreamLog.setValidator { priority, _ -\u003e\n  priority.level \u003e= Priority.DEBUG.level\n}\n```\n\n### CompositeStreamLogger\n\nYou can separate roles and behaviors for each different logger and composite the loggers into a single logger with `CompositeStreamLogger`.\n\n```kotlin\nval fileLogger = FileStreamLogger(fileLoggerConfig)\nval androidLogger = AndroidStreamLogger()\nval compositeLogger = CompositeStreamLogger(androidLogger, fileLogger)\nStreamLog.install(compositeLogger)\n```\n\n### Validator\n\nThe validator decides whether the log messages should be printed or not. You can set a validator to set the behaviors of your logger.\n\n```kotlin\n// Show log messages if the log priority is DEBUG or more than DEBUG.\nStreamLog.setValidator { priority, tag -\u003e\n    priority.level \u003e= Priority.DEBUG.level\n}\n\n// Show log messages if the tag contains a \"main\" string.\nStreamLog.setValidator { priority, tag -\u003e\n    tag.contains(\"main\")\n}\n```\n\n\u003cimg align=\"right\" width=\"90px\" src=\"https://user-images.githubusercontent.com/24237865/178630165-76855349-ac04-4474-8bcf-8eb5f8c41095.png\"/\u003e\n\n## Stream Log File\n\n**Stream Log File** is an extension library for persisting the log messages into an external `.txt` file.\n\n[![Maven Central](https://img.shields.io/maven-central/v/io.getstream/stream-log-file.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.getstream%22%20AND%20a:%22stream-log-file%22)\n\nAdd the dependency below into your **module**'s `build.gradle` file:\n\n```gradle\ndependencies {\n    implementation(\"io.getstream:stream-log:$version\")\n    debugImplementation(\"io.getstream:stream-log-file:$version\")\n}\n```\n\nIf you're targeting on Kotlin Multiplatform, add the dependency below to your module's `build.gradle.kts` file:\n\n```kotlin\nsourceSets {\n    val commonMain by getting {\n        dependencies {\n            implementation(\"io.getstream:stream-log:$version\")\n            debugImplementation(\"io.getstream:stream-log-file:$version\")\n        }\n    }\n}\n```\n\n### FileStreamLogger\n\nYou can persist the log messages that are triggered on runtime with `FileStreamLogger`. To persist your log messages into a file, you should use `FileStreamLogger` with `CompositeStreamLogger` like the example below:\n\n```kotlin\nval fileLoggerConfig = FileStreamLogger.Config(\n    filesDir = fileDirectory, // an internal file directory\n    externalFilesDir = null, // an external file directory. This is an optional.\n    app = FileStreamLogger.Config.App( // application information.\n        versionCode = 1,\n        versionName = \"1.0.0\"\n    ),\n    device = FileStreamLogger.Config.Device( // device information\n        model = \"%s %s\".format(Build.MANUFACTURER, Build.DEVICE),\n        androidApiLevel = Build.VERSION.SDK_INT\n    )\n)\nval fileLogger = FileStreamLogger(fileLoggerConfig)\nval kotlinLogger = KotlinStreamLogger()\nval compositeLogger = CompositeStreamLogger(kotlinLogger, fileLogger)\n\nStreamLog.install(compositeLogger)\n```\n\nThen you will get the result `.txt` file below:\n\n```\n======================================================================\nLogs date time: 2022-12-02 21:08:35'288\nVersion code: 1\nVersion name: 1.0.0\nAPI level: 10\nDevice: Stream's Mac\n======================================================================\n2022-11-30 13:02:29'918 D/              This is a log message\n2022-11-30 13:04:08'577 D/              ChatViewModel initialized\n2022-11-30 13:13:04'640 D/              ChatController initialized\n```\n\n\u003cimg align=\"right\" width=\"140px\" src=\"https://user-images.githubusercontent.com/24237865/205479526-5fa0b5f0-22df-4f02-ac0e-7a7a3e050cdb.png\"/\u003e\n\n## Stream Log Android File\n\n**Stream Log Android File** is an extension library for persisting your log messages into external `.txt` files. So you can record the runtime log messages into a `.txt` file, and it will help you to trace the log messages in many complex scenarios.\n\n[![Maven Central](https://img.shields.io/maven-central/v/io.getstream/stream-log-android.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.getstream%22%20AND%20a:%22stream-log-android-file%22)\n\nAdd the dependency below into your **module**'s `build.gradle` file:\n\n```gradle\ndependencies {\n    implementation(\"io.getstream:stream-log-android:$version\")\n    debugImplementation(\"io.getstream:stream-log-android-file:$version\")\n}\n```\n\n### AndroidStreamLogger\n\nFirst, you need to install a logger for Android with `AndroidStreamLogger` like the below:\n\n```kotlin\nclass App : Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n\n        AndroidStreamLogger.installOnDebuggableApp(this)\n    }\n}\n```\n\n\u003e**Note**: We'd recommend you install the logger only once in your application class.\n\nNow, you can print log messages simply like the below:\n\n```kotlin\nstreamLog { \"This is a log messages\" }\nstreamLog(priority = Priority.INFO, tag = \"Tag\") { \"This is a log messages\" }\nStreamLog.d(tag = \"Tag\") { \"This is a log message\" }\n```\n\n### Record Runtime Log Messages Into an External File\n\nYou don't need to do additional setup for this, because the `stream-log-android-file` dependency will execute all processes automatically. So let's extract the log messages into an external file following the command lines below on your terminal:\n\n1. Build and run your project on your emulator or connect to your real device over Wi-Fi following the [Connect to a device over Wi-Fi](https://developer.android.com/studio/command-line/adb#connect-to-a-device-over-wi-fi) guidelines.\n2. Enter in terminal: `adb shell am start-foreground-service -a io.getstream.log.android.CLEAR`\n3. You should see the toast message `Logs are cleared!`.\n4. Explore your app to record specific log messages.\n5. Enter in terminal: `adb shell am start-foreground-service -a io.getstream.log.android.SHARE`\n6. You should see a file-sharing dialog chooser in your device.\n7. Share the log file via other applications, such as Google Cloud.\n8. Exit recording log messages by enter in terminal: `adb shell am stopservice -a io.getstream.log.android.SHARE`\n\nThen you will get the result `.txt` file below:\n\n```\n======================================================================\nLogs date time: 2022-12-02 21:08:35'288\nVersion code: 1\nVersion name: 1.0.1\nAndroid API level: 31\nDevice: samsung beyond1\n======================================================================\n2022-11-30 13:02:29'918 D/              main:2 [Main]: onCreate MainActivity\n2022-11-30 13:13:06'656 D/              main:2 [Main]: Button clicked\n2022-11-30 13:13:07'225 D/              main:2 [Main]: Button clicked\n2022-11-30 13:13:07'439 D/              main:2 [Main]: Button clicked\n2022-11-30 13:14:23'316 D/              main:2 [Main]: onCreate MainActivity\n2022-11-30 13:14:24'296 D/              main:2 [Main]: Button clicked\n2022-11-30 13:14:24'723 D/              main:2 [Main]: Button clicked\n2022-11-30 16:36:39'102 D/              main:2 [MainActivity]: onCreate MainActivity\n2022-11-30 16:42:48'987 D/              main:2 [BoxScopeInstance]: Button Clicked!\n2022-11-30 16:42:49'873 D/              main:2 [BoxScopeInstance]: Button Clicked!\n```\n\n\u003ca href=\"https://getstream.io/chat/compose/tutorial/?utm_source=Github\u0026utm_campaign=Devrel_oss\u0026utm_medium=StreamLog\"\u003e\u003cimg src=\"https://user-images.githubusercontent.com/24237865/146505581-a79e8f7d-6eda-4611-b41a-d60f0189e7d4.jpeg\" align=\"right\" /\u003e\u003c/a\u003e\n\n## Find this library useful? :heart:\n\nSupport it by joining __[stargazers](https://github.com/getStream/stream-log/stargazers)__ for this repository. :star: \u003cbr\u003e\nAlso, follow **[Stream](https://twitter.com/getstream_io)** on Twitter for our next creations!\n\n# License\n```xml\nCopyright 2022 Stream.IO, Inc. All Rights Reserved.\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```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetstream%2Fstream-log","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetstream%2Fstream-log","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetstream%2Fstream-log/lists"}