Skip to content

Commit

Permalink
Add duration formatted and editorconfig file
Browse files Browse the repository at this point in the history
  • Loading branch information
ogesaku committed Feb 11, 2024
1 parent ade1094 commit 4468a72
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 19 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.{kt,kts}]
indent_size = 4
ktlint_code_style = intellij_idea
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = unset
ktlint_ignore_back_ticked_identifier = true
ktlint_function_signature_body_expression_wrapping = default
18 changes: 8 additions & 10 deletions klog/src/main/kotlin/com/coditory/klog/KlogContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ internal data class KlogContext(
companion object {
fun build(config: KlogConfig): KlogContext {
return KlogContext(
streams =
config.streams.mapIndexed { idx, stream ->
buildStream(idx, stream, config)
},
streams = config.streams.mapIndexed { idx, stream ->
buildStream(idx, stream, config)
},
clock = config.clock,
listener = config.listener,
klogErrLogger = config.klogErrLogger,
Expand All @@ -43,12 +42,11 @@ internal data class KlogContext(
val streamDescriptor = LogStreamDescriptor(streamIdx, config.filter)
val publishers =
config.publishers.mapIndexed { idx, publisher ->
val descriptor =
LogPublisherDescriptor(
stream = streamDescriptor,
publisherIdx = idx,
publisherType = publisher.javaClass,
)
val descriptor = LogPublisherDescriptor(
stream = streamDescriptor,
publisherIdx = idx,
publisherType = publisher.javaClass,
)
buildPublisher(descriptor, publisher, klogConfig)
}
return LogStream(
Expand Down
71 changes: 71 additions & 0 deletions klog/src/main/kotlin/com/coditory/klog/format/DurationFormat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.coditory.klog.format

import java.time.Duration
import kotlin.math.abs
import kotlin.math.round

object DurationFormat {
fun format(duration: Duration): String {
val ms = duration.toMillis()
return if (duration.isZero || ms != 0L) {
formatMillis(ms)
} else {
"${duration.toNanos()}ns"
}
}

fun formatMillis(ms: Long): String {
if (ms == 0L) {
return "0.00s"
}
val seconds = ms / 1000
val minutes = seconds / 60
val hours = minutes / 60
val days = hours / 24
return if (abs(days) > 0) {
val v = round(hours * 100 / 24.0) / 100.0
"%.2fd".format(v)
} else if (abs(hours) > 0) {
val v = round(minutes * 100 / 60.0) / 100.0
"%.2fh".format(v)
} else if (abs(minutes) > 0) {
val v = round(seconds * 100 / 60.0) / 100.0
"%.2fm".format(v)
} else if (abs(seconds) > 0) {
val v = round(ms * 100 / 1000.0) / 100.0
"%.2fs".format(v)
} else {
"${ms}ms"
}
}

fun formatSignificant(duration: Duration): String {
val ms = duration.toMillis()
return if (duration.isZero || ms != 0L) {
formatMillisSignificant(ms)
} else {
"${duration.toNanos()}ns"
}
}

fun formatMillisSignificant(ms: Long): String {
if (ms == 0L) {
return "0s"
}
val seconds = ms / 1000
val minutes = seconds / 60
val hours = minutes / 60
val days = hours / 24
return if (abs(days) > 0) {
"${days}d"
} else if (abs(hours) > 0) {
"${hours}h"
} else if (abs(minutes) > 0) {
"${minutes}m"
} else if (abs(seconds) > 0) {
"${seconds}s"
} else {
"${ms}ms"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package com.coditory.klog.publish
import com.coditory.klog.LogEvent
import com.coditory.klog.text.TextLogEventSerializer
import com.coditory.klog.text.plain.PlainTextLogEventSerializer
import com.coditory.klog.text.plain.PlainTextTimestampFormatter
import java.time.ZoneId
import java.time.format.DateTimeFormatter

class InMemoryTextPublisher(
private val serializer: TextLogEventSerializer = PlainTextLogEventSerializer(),
Expand Down Expand Up @@ -55,6 +58,9 @@ class InMemoryTextPublisher(
fun testPublisher(): InMemoryTextPublisher {
return InMemoryTextPublisher(
PlainTextLogEventSerializer(
timestampFormatter = PlainTextTimestampFormatter.from(
DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.of("UTC")),
),
threadFormatter = { _, appendable -> appendable.append(TEST_THREAD_NAME) },
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class PlainTextLogEventSerializer(
if (field.skip(event, mergeContextToItems)) continue
if (length < sized.length()) {
if (field == LogEventField.MESSAGE) {
sized.appendLazy(null)
sized.append(messageSeparator)
} else {
sized.appendLazy(' ')
Expand Down Expand Up @@ -124,10 +125,16 @@ class PlainTextLogEventSerializer(
fields = LogEventField.all(),
timestampFormatter = PlainTextTimestampFormatter.fromLocalTime(timestampStyle),
levelFormatter = levelFormatter,
loggerNameFormatter = PlainTextStringFormatter.builder().ansi(ansiResolved).compactSections().build(),
threadFormatter =
PlainTextStringFormatter.builder().ansi(ansiResolved).style(threadStyle).prefix("[")
.postfix("]").build(),
loggerNameFormatter = PlainTextStringFormatter.builder()
.ansi(ansiResolved)
.compactSections()
.build(),
threadFormatter = PlainTextStringFormatter.builder()
.ansi(ansiResolved)
.style(threadStyle)
.prefix("[")
.postfix("]")
.build(),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class SizedAppendable(
return length
}

fun appendLazy(csq: CharSequence): Appendable {
fun appendLazy(csq: CharSequence?): Appendable {
lazyAppend = csq
lazyAppendChar = null
return this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.coditory.klog
import com.coditory.klog.publish.InMemoryTextPublisher
import com.coditory.klog.publish.InMemoryTextPublisher.Companion.TEST_THREAD_NAME
import com.coditory.klog.shared.UpdatableFixedClock
import com.coditory.klog.shared.UpdatableFixedClock.Companion.DEFAULT_FIXED_TIME_LOG_STR
import com.coditory.klog.shared.UpdatableFixedClock.Companion.DEFAULT_FIXED_TIME_STR
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe

Expand All @@ -27,6 +27,6 @@ class KlogComplexPlainTextSpec : FunSpec({
test("should emit a basic info log event") {
logger.info { "Hello" }
publisher.getLogs().size shouldBe 1
publisher.getLastLog() shouldBe "$DEFAULT_FIXED_TIME_LOG_STR INFO $TEST_THREAD_NAME com.coditory.Logger: Hello"
publisher.getLastLog() shouldBe "$DEFAULT_FIXED_TIME_STR INFO $TEST_THREAD_NAME com.coditory.Logger: Hello"
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.coditory.klog.format

import io.kotest.core.spec.style.FunSpec
import io.kotest.core.tuple
import io.kotest.matchers.shouldBe
import java.time.Duration

class DurationFormatSpec : FunSpec({
listOf(
tuple(Duration.ofDays(0), "0.00s"),
tuple(Duration.ofDays(-3), "-3.00d"),
tuple(Duration.ofDays(3), "3.00d"),
tuple(Duration.ofHours(36), "1.50d"),
tuple(Duration.ofHours(24), "1.00d"),
tuple(Duration.ofHours(16), "16.00h"),
tuple(Duration.ofMinutes(110), "1.83h"),
tuple(Duration.ofMinutes(60), "1.00h"),
tuple(Duration.ofMinutes(35), "35.00m"),
tuple(Duration.ofSeconds(110), "1.83m"),
tuple(Duration.ofSeconds(60), "1.00m"),
tuple(Duration.ofSeconds(35), "35.00s"),
tuple(Duration.ofMillis(1100), "1.10s"),
tuple(Duration.ofMillis(1000), "1.00s"),
tuple(Duration.ofMillis(200), "200ms"),
tuple(Duration.ofNanos(1100000), "1ms"),
tuple(Duration.ofNanos(1000000), "1ms"),
tuple(Duration.ofNanos(1000), "1000ns"),
tuple(Duration.ofNanos(200), "200ns"),
tuple(Duration.ofNanos(-200), "-200ns"),
).forEach {
test("format: ${it.a} -> \"${it.b}\"") {
DurationFormat.format(it.a) shouldBe it.b
}
}

listOf(
tuple(Duration.ofDays(0), "0s"),
tuple(Duration.ofDays(-3), "-3d"),
tuple(Duration.ofDays(3), "3d"),
tuple(Duration.ofHours(36), "1d"),
tuple(Duration.ofHours(24), "1d"),
tuple(Duration.ofHours(16), "16h"),
tuple(Duration.ofMinutes(110), "1h"),
tuple(Duration.ofMinutes(60), "1h"),
tuple(Duration.ofMinutes(35), "35m"),
tuple(Duration.ofSeconds(110), "1m"),
tuple(Duration.ofSeconds(60), "1m"),
tuple(Duration.ofSeconds(35), "35s"),
tuple(Duration.ofMillis(1100), "1s"),
tuple(Duration.ofMillis(1000), "1s"),
tuple(Duration.ofMillis(200), "200ms"),
tuple(Duration.ofNanos(1100000), "1ms"),
tuple(Duration.ofNanos(1000000), "1ms"),
tuple(Duration.ofNanos(1000), "1000ns"),
tuple(Duration.ofNanos(200), "200ns"),
tuple(Duration.ofNanos(-200), "-200ns"),
).forEach {
test("format significant: ${it.a} -> \"${it.b}\"") {
DurationFormat.formatSignificant(it.a) shouldBe it.b
}
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ class UpdatableFixedClock(

companion object {
// Always use instant with nanos for testing. Some databases (like mongo) trim nanos - you should test for that!
val DEFAULT_FIXED_TIME_LOG_STR = "2015-12-03T11:15:30.123456+01:00"
val DEFAULT_FIXED_TIME = Instant.parse("2015-12-03T10:15:30.123456Z")
val DEFAULT_FIXED_TIME_STR = "2015-12-03T10:15:30.123456Z"
val DEFAULT_FIXED_TIME = Instant.parse(DEFAULT_FIXED_TIME_STR)
val DEFAULT_ZONE_ID = ZoneId.of("Europe/Warsaw")
}
}

0 comments on commit 4468a72

Please sign in to comment.