Skip to content

Commit

Permalink
Merge pull request #2 from bolteu/v.1.0.3
Browse files Browse the repository at this point in the history
V.1.0.3
  • Loading branch information
devindi authored Jan 15, 2021
2 parents 50feeb4 + f8d7d72 commit 1a0c8ae
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 30 deletions.
28 changes: 21 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
# Kalev

![Maven Central](https://img.shields.io/maven-central/v/eu.bolt/kalev?style=plastic)

Kalev is a structured logger for JVM (Java, Kotlin etc)

The idea of `Kalev` is pretty similar to `Timber`. Library provides `Kalevipoeg` interface with which you may implement various behaviour for log entries reaction.

## Packages

`kalev-lib` provides pure JVM implementation. Doesn't cotains any implementation of `Kalevipoeg`
`kalev-android` contains bridge between Kalev and Android's log system. `PrintPoeg` format log entry as JSON string and print it to LogCat
`kalev-lib` provides pure JVM implementation. Doesn't contains any implementation of `Kalevipoeg`
`kalev-android` contains bridge between Kalev and Android's log system. `PrintPoeg` format log entry as JSON string and print it to LogCat.
`kalev-okhttp` provide interceptor for `okhttp` to log network requests in Kalev-way


## Usage

Two easy steps:

1. Add any `Kalevipoeg` instances you want on application start. In Android application `onCreate` is a mosst suetable place
1. Add any `Kalevipoeg` instances you want on application start. In Android application `onCreate` is a most suitable place
2. Call Kalev's static methods everywhere throughout your app.

Check full Android sample at `sample` dir
Expand Down Expand Up @@ -96,27 +98,39 @@ Examples of network logs:
{
"message": "network",
"method": "GET",
"path": "\/gett",
"path": "\/unknown",
"id": "42",
"response.code": 404,
"response.body": "<!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 3.2 Final\/\/EN\">\n<title>404 Not Found<\/title>\n<h1>Not Found<\/h1>\n<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.<\/p>\n"
}
```

### FastLog
Kalev creates new object for every log entry which may abuse performance in case of stream of entries. You can go around of this issue with FastLog.

#### FastLog usage
There is `FastLog` interface which describes fast logger.
`kalev-lib` provides `SystemFastLog` implementation which prints messages to standard output stream
`kalev-android` provides `AndroidFastLog` implementation which prints messages to Android's LogCat
##### Initialisation:
`Kalev.fastLog = AndroidFastLog()`
##### Logging
`Kalev.fastLog?.v("Activity created")`

## Gradle
Add this to your dependencies block.
```
implementation 'eu.bolt:kalev:1.0.1'
implementation 'eu.bolt:kalev:$latest'
```

To use an android extension use this dependency instead:
```
implementation 'eu.bolt:kalev-android:1.0.1'
implementation 'eu.bolt:kalev-android:$latest'
```

Kalev-okhttp package:
```
implementation 'eu.bolt:kalev-okhttp:1.0.1'
implementation 'eu.bolt:kalev-okhttp:$latest'
```

## Naming
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ POM_LICENCE_DIST=repo
POM_DEVELOPER_ID=bolteu
POM_DEVELOPER_NAME=Bolt Technologies OÜ

VERSION_NAME=1.0.2
VERSION_NAME=1.0.3
25 changes: 25 additions & 0 deletions kalev-android/src/main/java/eu/bolt/kalev/AndroidFastLog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package eu.bolt.kalev

import android.util.Log
import eu.bolt.kalev.fast.FastLog
import eu.bolt.kalev.utils.generateTag

class AndroidFastLog : FastLog {

private val stackDepth = 3

override fun v(message: String, tag: String?) {
val finalTag = tag ?: generateTag(stackDepth)
Log.v(finalTag, message)
}

override fun d(message: String, tag: String?) {
val finalTag = tag ?: generateTag(stackDepth)
Log.d(finalTag, message)
}

override fun i(message: String, tag: String?) {
val finalTag = tag ?: generateTag(stackDepth)
Log.i(finalTag, message)
}
}
24 changes: 2 additions & 22 deletions kalev-android/src/main/java/eu/bolt/kalev/PrintPoeg.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package eu.bolt.kalev

import android.os.Build
import android.util.Log
import eu.bolt.kalev.utils.generateTag
import org.json.JSONObject
import java.util.regex.Pattern

class PrintPoeg : Kalevipoeg {

private val anonymousClassPattern = Pattern.compile("(\\$\\d+)+$")
private val maxTagLength = 23
private val callStackIndex = 6

override fun log(entry: LogEntry) {
Expand All @@ -22,24 +19,7 @@ class PrintPoeg : Kalevipoeg {
}

private fun getTag(entry: LogEntry): String {
return entry.tag ?: createStackElementTag()
}

private fun createStackElementTag(): String {
val stackTrace = Throwable().stackTrace
check(stackTrace.size > callStackIndex) { "Synthetic stacktrace didn't have enough elements: are you using proguard?" }
val element = stackTrace[callStackIndex]

var tag = element.className
val matcher = anonymousClassPattern.matcher(tag)
if (matcher.find()) {
tag = matcher.replaceAll("")
}
tag = tag.substring(tag.lastIndexOf('.') + 1)
// Tag length limit was removed in API 24.
return if (tag.length <= maxTagLength || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
tag
} else tag.substring(0, maxTagLength)
return entry.tag ?: generateTag(callStackIndex)
}

private fun LogEntry.formatString(): String {
Expand Down
24 changes: 24 additions & 0 deletions kalev-android/src/main/java/eu/bolt/kalev/utils/TagGenerator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package eu.bolt.kalev.utils

import android.os.Build
import java.util.regex.Pattern

private val anonymousClassPattern = Pattern.compile("(\\$\\d+)+$")
private const val maxTagLength = 23

internal fun generateTag(stackDepth: Int): String {
val stackTrace = Throwable().stackTrace
check(stackTrace.size > stackDepth) { "Synthetic stacktrace didn't have enough elements: are you using proguard?" }
val element = stackTrace[stackDepth]

var tag = element.className
val matcher = anonymousClassPattern.matcher(tag)
if (matcher.find()) {
tag = matcher.replaceAll("")
}
tag = tag.substring(tag.lastIndexOf('.') + 1)
// Tag length limit was removed in API 24.
return if (tag.length <= maxTagLength || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
tag
} else tag.substring(0, maxTagLength)
}
7 changes: 7 additions & 0 deletions kalev-lib/src/main/java/eu/bolt/kalev/Kalev.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package eu.bolt.kalev

import eu.bolt.kalev.fast.FastLog

@Suppress("MemberVisibilityCanBePrivate", "unused")
object Kalev {

Expand All @@ -16,6 +18,11 @@ object Kalev {
var nop = false
private val nopEntry = NopLogEntry

/**
* FastLog can be used for performance-sensitive logging. Note that FastLog will NOT trigger log consumers
*/
var fastLog: FastLog? = null

private val consumers = mutableListOf<Kalevipoeg>()

@JvmStatic
Expand Down
10 changes: 10 additions & 0 deletions kalev-lib/src/main/java/eu/bolt/kalev/fast/FastLog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package eu.bolt.kalev.fast

interface FastLog {

fun v(message: String, tag: String? = null)

fun d(message: String, tag: String? = null)

fun i(message: String, tag: String? = null)
}
27 changes: 27 additions & 0 deletions kalev-lib/src/main/java/eu/bolt/kalev/fast/SystemFastLog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package eu.bolt.kalev.fast

/**
* Default [FastLog] implementation which prints the logs to standard output
*/
class SystemFastLog : FastLog {

override fun v(message: String, tag: String?) {
print(message, tag)
}

override fun d(message: String, tag: String?) {
print(message, tag)
}

override fun i(message: String, tag: String?) {
print(message, tag)
}

private fun print(message: String, tag: String?) {
if (tag == null) {
println(message)
} else {
println(StringBuilder(tag).append(": ").append(message).toString())
}
}
}
4 changes: 4 additions & 0 deletions sample/src/main/java/eu/bolt/kalev/sample/SampleActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ class SampleActivity : Activity() {
findViewById<View>(R.id.click).setOnClickListener {
clickCounter += 1
Kalev.with("counter", clickCounter).d("Click")
Kalev.fastLog?.d("Click")
}

findViewById<View>(R.id.networkGet).setOnClickListener {
networkDemo.doGet()
Kalev.fastLog?.d("Started network request")
}

findViewById<View>(R.id.networkErr).setOnClickListener {
networkDemo.doNotFound()
Kalev.fastLog?.d("Started network request")
}

Kalev.d("On start")
Kalev.fastLog?.v("Activity created")
}
}
3 changes: 3 additions & 0 deletions sample/src/main/java/eu/bolt/kalev/sample/SampleApp.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package eu.bolt.kalev.sample

import android.app.Application
import eu.bolt.kalev.AndroidFastLog
import eu.bolt.kalev.Kalev
import eu.bolt.kalev.PrintPoeg
import eu.bolt.kalev.fast.SystemFastLog

class SampleApp : Application() {

Expand All @@ -11,6 +13,7 @@ class SampleApp : Application() {

if (BuildConfig.DEBUG) {
Kalev.addPoeg(PrintPoeg())
Kalev.fastLog = AndroidFastLog()
}
}
}

0 comments on commit 1a0c8ae

Please sign in to comment.