-
Notifications
You must be signed in to change notification settings - Fork 80
SAM Type Interface #920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
Jay-Lokhande
wants to merge
65
commits into
typelevel:main
Choose a base branch
from
Jay-Lokhande:feature/log4cats-sam-type
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
SAM Type Interface #920
Changes from all commits
Commits
Show all changes
65 commits
Select commit
Hold shift + click to select a range
485b98b
Added Logger Kernel Initial File
Jay-Lokhande 8d8223f
sbt scalafmt
Jay-Lokhande f6e9d55
added withMethodName method
Jay-Lokhande e7f0be4
added more SAM type specific files
Jay-Lokhande 7f6dc0e
changed LogLevel to remove conflict
Jay-Lokhande 9c3c243
going back to LogLevel name
Jay-Lokhande 9908c00
original WriterTLogger
Jay-Lokhande 4fb2850
deleted DefferedLogLevel
Jay-Lokhande fc58670
build.sbt
Jay-Lokhande 23b2094
scalafmt
Jay-Lokhande 3f1f34c
sbt scalafmtSbt
Jay-Lokhande 7961c15
added KernelLogLevel
Jay-Lokhande a5708c3
add new samlogger interface based on old and poc logger
Jay-Lokhande 649468d
add SamStructuredLogger that delegates to LoggerKernel, with original…
Jay-Lokhande ac5aaee
modify log with parameterized with the context type
Jay-Lokhande 53dda4f
change datatype double to int and use cats Order
Jay-Lokhande 634de7d
update LoggerKernel to use new Log.scala
Jay-Lokhande b7f0d10
update LogRecord and Recordable to use paramerterized Log
Jay-Lokhande 859753b
update ConsoleLogger to original, JsonLike
Jay-Lokhande ac1a39b
remove unused Context.Encoder
Jay-Lokhande 3beb5f7
Merge branch 'typelevel:main' into feature/log4cats-sam-type
Jay-Lokhande 44ab02b
remove JsonLike Structure instead bypass it direct
Jay-Lokhande 10b0c81
modify files to adapt new change
Jay-Lokhande 4b746e2
update log.scala
Jay-Lokhande 2ad479c
update recordable
Jay-Lokhande 842bb7e
update Log.scala
Jay-Lokhande fd6bab1
update log.scala
Jay-Lokhande 63ba4c4
update Log.scala
Jay-Lokhande 5b85513
update with the suggested changes
Jay-Lokhande 022f96b
use builder for the context
Jay-Lokhande 3d00cf9
add sourcecode stable version
Jay-Lokhande 17cb902
sbt scalafmt
Jay-Lokhande 3df4963
sbt scalafmt
Jay-Lokhande 4602d56
add foreach loop instead forALL
Jay-Lokhande f139d0c
resolve sourcecode scalanavative error
Jay-Lokhande 401c5ad
fix sourcecode library issue
Jay-Lokhande f88c446
sbt scalafmtSbt
Jay-Lokhande 10cd36c
add test suites
Jay-Lokhande e8dd135
fix test error
Jay-Lokhande f9364f1
fix dateTimeFormatter error
Jay-Lokhande aafe9ba
add Noop Logger with tests
Jay-Lokhande ad0143e
remove unwanted file
Jay-Lokhande bd68364
remove LogRecord Recordable and SamLoggerAdapter
Jay-Lokhande d19ffae
update core's extras
Jay-Lokhande 749fd3d
update old interfaces with logger kernel functionality
Jay-Lokhande 72376e8
remove SamLoggerAdaptorTest
Jay-Lokhande b0ddff1
update sam implementation after removing LogRecor and Recordable
Jay-Lokhande 58f2b51
update test suite
Jay-Lokhande b606c3b
update js-console ConsoleLogger
Jay-Lokhande 6962ff8
update slf4j Logger Internel
Jay-Lokhande 041375c
update testing module with LoggerKernel
Jay-Lokhande 468114f
update NoOp Logger
Jay-Lokhande cb28f49
Merge branch 'typelevel:main' into feature/log4cats-sam-type
Jay-Lokhande f695de3
Merge branch 'feature/log4cats-sam-type' of https://github.com/Jay-Lo…
Jay-Lokhande f6bf9a3
fix match level error
Jay-Lokhande 329bc40
fix match error
Jay-Lokhande a32d908
fix match error
Jay-Lokhande 809e560
fir test errors
Jay-Lokhande 1b7aeb9
try differentt fix
Jay-Lokhande 2a9fe26
fix tests
Jay-Lokhande 3a13966
sbt scala format
Jay-Lokhande 0f8c152
update mima Binary issues
Jay-Lokhande 21b3e6c
add MiMa Exclusions
Jay-Lokhande e69b27d
remove sourcecode
Jay-Lokhande 8bbf794
remove java.util time class as suggested
Jay-Lokhande File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
core/shared/src/main/scala/org/typelevel/log4cats/ConsoleLoggerKernel.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright 2018 Typelevel | ||
* | ||
* 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. | ||
*/ | ||
|
||
package org.typelevel.log4cats | ||
|
||
import cats.effect.kernel.Sync | ||
|
||
/** | ||
* A simple console implementation of LoggerKernel for testing the SAM design. | ||
*/ | ||
class ConsoleLoggerKernel[F[_], Ctx](implicit F: Sync[F]) extends LoggerKernel[F, Ctx] { | ||
|
||
def log(level: KernelLogLevel, record: Log.Builder[Ctx] => Log.Builder[Ctx]): F[Unit] = { | ||
F.delay { | ||
val logRecord = record(Log.mutableBuilder[Ctx]()).build() | ||
|
||
val timestamp = logRecord.timestamp.getOrElse(java.time.Instant.now()) | ||
val timeStr = timestamp.toString | ||
|
||
val levelStr = logRecord.level.namePadded | ||
val message = logRecord.message | ||
val className = logRecord.className.map(c => s"[$c]").getOrElse("") | ||
val fileName = | ||
logRecord.fileName.map(f => s"($f:${logRecord.line.getOrElse(0)})").getOrElse("") | ||
|
||
val contextStr = if (logRecord.context.nonEmpty) { | ||
val contextPairs = logRecord.context.map { case (k, v) => s"$k=$v" }.mkString(", ") | ||
s" {$contextPairs}" | ||
} else "" | ||
|
||
val throwableStr = logRecord.throwable.map(t => s"\n${t.toString}").getOrElse("") | ||
|
||
val logLine = s"$timeStr $levelStr $className$fileName$contextStr $message$throwableStr" | ||
|
||
println(logLine) | ||
} | ||
} | ||
} | ||
|
||
object ConsoleLoggerKernel { | ||
def apply[F[_], Ctx](implicit F: Sync[F]): ConsoleLoggerKernel[F, Ctx] = | ||
new ConsoleLoggerKernel[F, Ctx] | ||
} |
57 changes: 57 additions & 0 deletions
57
core/shared/src/main/scala/org/typelevel/log4cats/Context.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright 2018 Typelevel | ||
* | ||
* 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. | ||
*/ | ||
|
||
package org.typelevel.log4cats | ||
|
||
import scala.concurrent.duration.FiniteDuration | ||
|
||
import org.typelevel.log4cats.Context.Encoder | ||
|
||
/** | ||
* A value that can be written into a json-like construct, provided a visitor. | ||
*/ | ||
trait Context[C] { | ||
def capture[A](a: A)(implicit E: Encoder[A, C]): C | ||
} | ||
|
||
object Context { | ||
trait Encoder[A, B] { | ||
def encode(a: A): B | ||
} | ||
|
||
object Encoder { | ||
def apply[A, B](implicit ev: Encoder[A, B]): ev.type = ev | ||
|
||
// Identity encoder for when input and output types are the same | ||
implicit def identityEncoder[A]: Encoder[A, A] = a => a | ||
|
||
implicit val stringToStringEncoder: Encoder[String, String] = a => a | ||
|
||
implicit val intToStringEncoder: Encoder[Int, String] = _.toString | ||
|
||
implicit val longToStringEncoder: Encoder[Long, String] = _.toString | ||
|
||
implicit val doubleToStringEncoder: Encoder[Double, String] = _.toString | ||
|
||
implicit val booleanToStringEncoder: Encoder[Boolean, String] = if (_) "true" else "false" | ||
|
||
// Removed Instant encoder for Scala Native compatibility | ||
// implicit val instantToStringEncoder: Encoder[Instant, String] = | ||
// DateTimeFormatter.ISO_INSTANT.format(_) | ||
|
||
implicit val finiteDurationToStringEncoder: Encoder[FiniteDuration, String] = _.toString | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
core/shared/src/main/scala/org/typelevel/log4cats/KernelLogLevel.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright 2018 Typelevel | ||
* | ||
* 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. | ||
*/ | ||
|
||
package org.typelevel.log4cats | ||
|
||
import cats.Order | ||
|
||
final case class KernelLogLevel(name: String, value: Int) { | ||
def namePadded: String = name.padTo(5, ' ').mkString | ||
} | ||
|
||
object KernelLogLevel { | ||
implicit final val orderKernelLogLevel: Order[KernelLogLevel] = | ||
Order.by[KernelLogLevel, Int](-_.value) | ||
|
||
val Trace: KernelLogLevel = KernelLogLevel("TRACE", 100) | ||
val Debug: KernelLogLevel = KernelLogLevel("DEBUG", 200) | ||
val Info: KernelLogLevel = KernelLogLevel("INFO", 300) | ||
val Warn: KernelLogLevel = KernelLogLevel("WARN", 400) | ||
val Error: KernelLogLevel = KernelLogLevel("ERROR", 500) | ||
val Fatal: KernelLogLevel = KernelLogLevel("FATAL", 600) | ||
} |
193 changes: 193 additions & 0 deletions
193
core/shared/src/main/scala/org/typelevel/log4cats/Log.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/* | ||
* Copyright 2018 Typelevel | ||
* | ||
* 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. | ||
*/ | ||
|
||
package org.typelevel.log4cats | ||
|
||
import scala.collection.mutable | ||
import scala.concurrent.duration.FiniteDuration | ||
|
||
/** | ||
* Low-level interface exposing methods to enrich a log record with relevant information. The | ||
* methods are designed to capture elements that cannot be easily captured from a monadic context | ||
* (or by running an effect). Elements such as timestamps should be provided by means of | ||
* middlewares. | ||
*/ | ||
trait Log[Ctx] { | ||
def timestamp: Option[FiniteDuration] | ||
def level: KernelLogLevel | ||
def message: () => String | ||
def throwable: Option[Throwable] | ||
def context: Map[String, Ctx] | ||
def fileName: Option[String] | ||
def className: Option[String] | ||
def methodName: Option[String] | ||
def line: Option[Int] | ||
def levelValue: Int | ||
} | ||
|
||
object Log { | ||
trait Builder[Ctx] { | ||
def withTimestamp(value: FiniteDuration): Builder[Ctx] | ||
def withLevel(level: KernelLogLevel): Builder[Ctx] | ||
def withMessage(message: => String): Builder[Ctx] | ||
def withThrowable(throwable: Throwable): Builder[Ctx] | ||
def withContext[A](name: String)(ctx: A)(implicit E: Context.Encoder[A, Ctx]): Builder[Ctx] | ||
def withFileName(name: String): Builder[Ctx] | ||
def withClassName(name: String): Builder[Ctx] | ||
def withMethodName(name: String): Builder[Ctx] | ||
def withLine(line: Int): Builder[Ctx] | ||
|
||
final def withContextMap[A]( | ||
contextMap: Map[String, A] | ||
)(implicit E: Context.Encoder[A, Ctx]): Builder[Ctx] = | ||
contextMap.foldLeft(this) { case (builder, (k, v)) => builder.withContext(k)(v) } | ||
|
||
def adaptTimestamp(f: FiniteDuration => FiniteDuration): Builder[Ctx] | ||
def adaptLevel(f: KernelLogLevel => KernelLogLevel): Builder[Ctx] | ||
def adaptMessage(f: String => String): Builder[Ctx] | ||
def adaptThrowable(f: Throwable => Throwable): Builder[Ctx] | ||
def adaptContext(f: Map[String, Ctx] => Map[String, Ctx]): Builder[Ctx] | ||
def adaptFileName(f: String => String): Builder[Ctx] | ||
def adaptClassName(f: String => String): Builder[Ctx] | ||
def adaptMethodName(f: String => String): Builder[Ctx] | ||
def adaptLine(f: Int => Int): Builder[Ctx] | ||
|
||
def build(): Log[Ctx] | ||
} | ||
|
||
def mutableBuilder[Ctx](): Builder[Ctx] = new MutableBuilder[Ctx]() | ||
|
||
private class MutableBuilder[Ctx] extends Builder[Ctx] { | ||
private var _timestamp: Option[FiniteDuration] = None | ||
private var _level: KernelLogLevel = KernelLogLevel.Info | ||
private var _message: () => String = () => "" | ||
private var _throwable: Option[Throwable] = None | ||
private var _context: mutable.Builder[(String, Ctx), Map[String, Ctx]] = | ||
Map.newBuilder[String, Ctx] | ||
private var _fileName: Option[String] = None | ||
private var _className: Option[String] = None | ||
private var _methodName: Option[String] = None | ||
private var _line: Option[Int] = None | ||
|
||
def build(): Log[Ctx] = new Log[Ctx] { | ||
override def timestamp: Option[FiniteDuration] = _timestamp | ||
override def level: KernelLogLevel = _level | ||
override def message: () => String = _message | ||
override def throwable: Option[Throwable] = _throwable | ||
override def context: Map[String, Ctx] = _context.result() | ||
override def className: Option[String] = _className | ||
override def fileName: Option[String] = _fileName | ||
override def methodName: Option[String] = _methodName | ||
override def line: Option[Int] = _line.filter(_ > 0) | ||
override def levelValue: Int = _level.value | ||
} | ||
|
||
override def withTimestamp(value: FiniteDuration): this.type = { | ||
_timestamp = Some(value) | ||
this | ||
} | ||
|
||
override def withLevel(level: KernelLogLevel): this.type = { | ||
_level = level | ||
this | ||
} | ||
|
||
override def withMessage(message: => String): this.type = { | ||
_message = () => message | ||
this | ||
} | ||
|
||
override def adaptMessage(f: String => String): this.type = { | ||
val originalMessage = _message | ||
_message = () => f(originalMessage()) | ||
this | ||
} | ||
|
||
override def adaptTimestamp(f: FiniteDuration => FiniteDuration): this.type = { | ||
_timestamp = _timestamp.map(f) | ||
this | ||
} | ||
|
||
override def adaptLevel(f: KernelLogLevel => KernelLogLevel): this.type = { | ||
_level = f(_level) | ||
this | ||
} | ||
|
||
override def adaptThrowable(f: Throwable => Throwable): this.type = { | ||
_throwable = _throwable.map(f) | ||
this | ||
} | ||
|
||
override def adaptContext(f: Map[String, Ctx] => Map[String, Ctx]): this.type = { | ||
val currentContext = _context.result() | ||
_context = Map.newBuilder[String, Ctx] | ||
f(currentContext).foreach { case (k, v) => _context += (k -> v) } | ||
this | ||
} | ||
|
||
override def adaptFileName(f: String => String): this.type = { | ||
_fileName = _fileName.map(f) | ||
this | ||
} | ||
|
||
override def adaptClassName(f: String => String): this.type = { | ||
_className = _className.map(f) | ||
this | ||
} | ||
|
||
override def adaptMethodName(f: String => String): this.type = { | ||
_methodName = _methodName.map(f) | ||
this | ||
} | ||
|
||
override def adaptLine(f: Int => Int): this.type = { | ||
_line = _line.map(f) | ||
this | ||
} | ||
|
||
override def withThrowable(throwable: Throwable): this.type = { | ||
_throwable = Some(throwable) | ||
this | ||
} | ||
|
||
override def withContext[A]( | ||
name: String | ||
)(ctx: A)(implicit E: Context.Encoder[A, Ctx]): this.type = { | ||
_context += (name -> E.encode(ctx)) | ||
this | ||
} | ||
|
||
override def withFileName(name: String): this.type = { | ||
_fileName = Some(name) | ||
this | ||
} | ||
|
||
override def withClassName(name: String): this.type = { | ||
_className = Some(name) | ||
this | ||
} | ||
|
||
override def withMethodName(name: String): this.type = { | ||
_methodName = Some(name) | ||
this | ||
} | ||
|
||
override def withLine(line: Int): this.type = { | ||
_line = if (line > 0) Some(line) else None | ||
this | ||
} | ||
} | ||
morgen-peschke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.