Skip to content

Commit

Permalink
Merge branch 'main' into ks/ABIValidation
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinSchildhorn committed Nov 20, 2024
2 parents 03a8b7d + c9af0b7 commit ccdd2e0
Show file tree
Hide file tree
Showing 18 changed files with 451 additions and 28 deletions.
6 changes: 5 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ koin-core = "3.5.3"
koin-android = "3.5.3"
koin-test = "3.5.3"
coroutines = "1.7.3"
kotlinx-datetime = "0.6.1"
kotlinx-io = "0.5.4"
roboelectric = "4.10.3"
buildConfig = "4.1.2"
mavenPublish = "0.27.0"
Expand Down Expand Up @@ -61,6 +63,8 @@ testhelp = { module = "co.touchlab:testhelp", version.ref = "testhelp" }
koin = { module = "io.insert-koin:koin-core", version.ref = "koin-core" }
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin-android" }
coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
kotlinx-io = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version.ref = "kotlinx-io" }
roboelectric = { module = "org.robolectric:robolectric", version.ref = "roboelectric" }

koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin-test" }
Expand Down Expand Up @@ -90,4 +94,4 @@ android = [
"androidx-navigationFragment",
"androidx-navigationUI",
"androidx-coordinatorLayout",
]
]
28 changes: 17 additions & 11 deletions kermit-core/src/appleMain/kotlin/co/touchlab/kermit/OSLogWriter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ package co.touchlab.kermit

import co.touchlab.kermit.darwin.*
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.ptr
import platform.darwin.OS_LOG_DEFAULT
import platform.darwin.OS_LOG_TYPE_DEBUG
import platform.darwin.OS_LOG_TYPE_DEFAULT
import platform.darwin.OS_LOG_TYPE_ERROR
Expand All @@ -27,12 +25,12 @@ import kotlin.experimental.ExperimentalNativeApi
*/
open class OSLogWriter internal constructor(
private val messageStringFormatter: MessageStringFormatter,
private val darwinLogger: DarwinLogger
private val darwinLogger: DarwinLogger,
) : LogWriter() {

constructor(messageStringFormatter: MessageStringFormatter = DefaultFormatter) : this(
constructor(messageStringFormatter: MessageStringFormatter = DefaultFormatter, subsystem: String = "", category: String = "", publicLogging: Boolean = false) : this(
messageStringFormatter,
DarwinLoggerActual
DarwinLoggerActual(subsystem, category, publicLogging),
)

override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
Expand All @@ -54,9 +52,8 @@ open class OSLogWriter internal constructor(
}
}

@OptIn(ExperimentalNativeApi::class)
open fun logThrowable(osLogSeverity: os_log_type_t, throwable: Throwable) {
darwinLogger.log(osLogSeverity, throwable.getStackTrace().joinToString("\n"))
darwinLogger.log(osLogSeverity, throwable.stackTraceToString())
}

private fun kermitSeverityToOsLogType(severity: Severity): os_log_type_t = when (severity) {
Expand All @@ -77,9 +74,18 @@ internal interface DarwinLogger {
}

@OptIn(ExperimentalForeignApi::class)
private object DarwinLoggerActual : DarwinLogger {
private val logger = darwin_log_create("", "")!!
private class DarwinLoggerActual(subsystem: String, category: String, publicLogging: Boolean) : DarwinLogger {
private val logger = darwin_log_create(subsystem, category)!!
// see https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code?language=objc
// iOS considers everything coming from Kermit as a dynamic string, so without publicLogging=true, all logs are
// private
private val darwinLogFn: (osLogSeverity: os_log_type_t, message: String) -> Unit = if (publicLogging) {
{ osLogSeverity, message -> darwin_log_public_with_type(logger, osLogSeverity, message) }
} else {
{ osLogSeverity, message -> darwin_log_with_type(logger, osLogSeverity, message) }
}

override fun log(osLogSeverity: os_log_type_t, message: String) {
darwin_log_with_type(logger, osLogSeverity, message)
darwinLogFn(osLogSeverity, message)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ open class XcodeSeverityWriter(private val messageStringFormatter: MessageString
override fun formatMessage(severity: Severity, tag: Tag, message: Message): String =
"${emojiPrefix(severity)} ${messageStringFormatter.formatMessage(null, tag, message)}"

@OptIn(ExperimentalNativeApi::class)
override fun logThrowable(osLogSeverity: os_log_type_t, throwable: Throwable) {
// oslog cuts off longer strings, so for local development, println is more useful
println(throwable.getStackTrace().joinToString("\n"))
println(throwable.stackTraceToString())
}

//If this looks familiar, yes, it came directly from Napier :) https://github.com/AAkira/Napier#darwinios-macos-watchos-tvosintelapple-silicon
Expand Down
9 changes: 9 additions & 0 deletions kermit-core/src/nativeInterop/cInterop/os_log.def
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ darwin_os_log_t darwin_log_create(const char *subsystem, const char *category) {
void darwin_log_with_type(darwin_os_log_t log, os_log_type_t type, const char *msg) {
os_log_with_type((os_log_t)log, type, "%s", msg);
}

/**
* Uses format specifier %{public}s to make logging public.
* See https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code?language=objc.
* We cannot pass the format specifier from Kotlin, as the API requires the value to be a string constant.
*/
void darwin_log_public_with_type(darwin_os_log_t log, os_log_type_t type, const char *msg) {
os_log_with_type((os_log_t)log, type, "%{public}s", msg);
}
28 changes: 28 additions & 0 deletions kermit-io/api/android/kermit-io.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
public class co/touchlab/kermit/io/RollingFileLogWriter : co/touchlab/kermit/LogWriter {
public fun <init> (Lco/touchlab/kermit/io/RollingFileLogWriterConfig;Lco/touchlab/kermit/MessageStringFormatter;Lkotlinx/datetime/Clock;Lkotlinx/io/files/FileSystem;)V
public synthetic fun <init> (Lco/touchlab/kermit/io/RollingFileLogWriterConfig;Lco/touchlab/kermit/MessageStringFormatter;Lkotlinx/datetime/Clock;Lkotlinx/io/files/FileSystem;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun log (Lco/touchlab/kermit/Severity;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V
}

public final class co/touchlab/kermit/io/RollingFileLogWriterConfig {
public fun <init> (Ljava/lang/String;Lkotlinx/io/files/Path;JIZZ)V
public synthetic fun <init> (Ljava/lang/String;Lkotlinx/io/files/Path;JIZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Lkotlinx/io/files/Path;
public final fun component3 ()J
public final fun component4 ()I
public final fun component5 ()Z
public final fun component6 ()Z
public final fun copy (Ljava/lang/String;Lkotlinx/io/files/Path;JIZZ)Lco/touchlab/kermit/io/RollingFileLogWriterConfig;
public static synthetic fun copy$default (Lco/touchlab/kermit/io/RollingFileLogWriterConfig;Ljava/lang/String;Lkotlinx/io/files/Path;JIZZILjava/lang/Object;)Lco/touchlab/kermit/io/RollingFileLogWriterConfig;
public fun equals (Ljava/lang/Object;)Z
public final fun getLogFileName ()Ljava/lang/String;
public final fun getLogFilePath ()Lkotlinx/io/files/Path;
public final fun getLogTag ()Z
public final fun getMaxLogFiles ()I
public final fun getPrependTimestamp ()Z
public final fun getRollOnSize ()J
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

28 changes: 28 additions & 0 deletions kermit-io/api/jvm/kermit-io.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
public class co/touchlab/kermit/io/RollingFileLogWriter : co/touchlab/kermit/LogWriter {
public fun <init> (Lco/touchlab/kermit/io/RollingFileLogWriterConfig;Lco/touchlab/kermit/MessageStringFormatter;Lkotlinx/datetime/Clock;Lkotlinx/io/files/FileSystem;)V
public synthetic fun <init> (Lco/touchlab/kermit/io/RollingFileLogWriterConfig;Lco/touchlab/kermit/MessageStringFormatter;Lkotlinx/datetime/Clock;Lkotlinx/io/files/FileSystem;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun log (Lco/touchlab/kermit/Severity;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V
}

public final class co/touchlab/kermit/io/RollingFileLogWriterConfig {
public fun <init> (Ljava/lang/String;Lkotlinx/io/files/Path;JIZZ)V
public synthetic fun <init> (Ljava/lang/String;Lkotlinx/io/files/Path;JIZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Lkotlinx/io/files/Path;
public final fun component3 ()J
public final fun component4 ()I
public final fun component5 ()Z
public final fun component6 ()Z
public final fun copy (Ljava/lang/String;Lkotlinx/io/files/Path;JIZZ)Lco/touchlab/kermit/io/RollingFileLogWriterConfig;
public static synthetic fun copy$default (Lco/touchlab/kermit/io/RollingFileLogWriterConfig;Ljava/lang/String;Lkotlinx/io/files/Path;JIZZILjava/lang/Object;)Lco/touchlab/kermit/io/RollingFileLogWriterConfig;
public fun equals (Ljava/lang/Object;)Z
public final fun getLogFileName ()Ljava/lang/String;
public final fun getLogFilePath ()Lkotlinx/io/files/Path;
public final fun getLogTag ()Z
public final fun getMaxLogFiles ()I
public final fun getPrependTimestamp ()Z
public final fun getRollOnSize ()J
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

100 changes: 100 additions & 0 deletions kermit-io/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2024 Touchlab
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("com.android.library")
kotlin("multiplatform")
id("com.vanniktech.maven.publish")
}

kotlin {
androidTarget {
publishAllLibraryVariants()
}
jvm()

macosX64()
macosArm64()
iosX64()
iosArm64()
iosSimulatorArm64()
watchosArm32()
watchosArm64()
watchosSimulatorArm64()
watchosDeviceArm64()
watchosX64()
tvosArm64()
tvosSimulatorArm64()
tvosX64()

mingwX64()
linuxX64()
linuxArm64()

androidNativeArm32()
androidNativeArm64()
androidNativeX86()
androidNativeX64()

@Suppress("OPT_IN_USAGE")
applyDefaultHierarchyTemplate {
common {
group("commonJvm") {
withAndroidTarget()
withJvm()
}
}
}

sourceSets {
commonMain.dependencies {
implementation(project(":kermit-core"))

api(libs.kotlinx.datetime)
api(libs.kotlinx.io)
implementation(libs.coroutines)
}

commonTest.dependencies {
implementation(kotlin("test"))
implementation(project(":kermit-test"))
}

getByName("commonJvmTest").dependencies {
implementation(kotlin("test-junit"))
}

getByName("androidUnitTest").dependencies {
implementation(libs.androidx.runner)
implementation(libs.roboelectric)
}
}
}

android {
namespace = "co.touchlab.kermit.io"
compileSdk = libs.versions.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.minSdk.get().toInt()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}

tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
Loading

0 comments on commit ccdd2e0

Please sign in to comment.