-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
193 additions
and
137 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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 |
---|---|---|
@@ -1 +1 @@ | ||
APIDOCS_SERVER_URL=https://graalnative4s.usommerl.dev,APIDOCS_DESCRIPTION="[github.com/usommerl/graalnative4s](https://github.com/usommerl/graalnative4s)" | ||
APIDOCS_SERVER_URL=https://graalnative4s.usommerl.dev,APIDOCS_DESCRIPTION="[github.com/usommerl/graalnative4s](https://github.com/usommerl/graalnative4s)",LOG_FORMATTER="default" |
This file contains 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
This file contains 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
This file contains 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 |
---|---|---|
@@ -1 +1 @@ | ||
sbt.version=1.4.7 | ||
sbt.version=1.5.0 |
This file contains 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 |
---|---|---|
@@ -1,10 +1,10 @@ | ||
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.26") | ||
addSbtPlugin("com.alejandrohdezma" % "sbt-codecov" % "0.2.0") | ||
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.27") | ||
addSbtPlugin("com.alejandrohdezma" % "sbt-codecov" % "0.2.1") | ||
addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") | ||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0") | ||
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") | ||
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.0") | ||
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.16") | ||
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.1") | ||
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.17") | ||
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") | ||
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1") | ||
addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "1.8.2") |
This file contains 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
This file contains 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,62 @@ | ||
package app | ||
|
||
import cats.implicits._ | ||
import ciris._ | ||
import ciris.refined._ | ||
import eu.timepit.refined.api.Refined | ||
import eu.timepit.refined.auto._ | ||
import eu.timepit.refined.string.Url | ||
import eu.timepit.refined.types.net.PortNumber | ||
import io.odin.Level | ||
import io.odin.formatter.Formatter | ||
import io.odin.json.{Formatter => JFormatter} | ||
|
||
import app.ServerUrl | ||
|
||
case class Config(server: ServerConfig, logger: LoggerConfig) | ||
case class ServerConfig(port: PortNumber, apiDocs: ApiDocsConfig) | ||
case class ApiDocsConfig(serverUrl: ServerUrl, description: Option[String]) | ||
case class LoggerConfig(level: Level, formatter: Formatter) | ||
|
||
package object app { | ||
|
||
type ServerUrl = String Refined Url | ||
|
||
implicit val logLevelDecoder: ConfigDecoder[String, Level] = | ||
ConfigDecoder[String, String].mapOption("Level")(_.toLowerCase match { | ||
case "trace" => Level.Trace.some | ||
case "debug" => Level.Debug.some | ||
case "info" => Level.Info.some | ||
case "warn" => Level.Warn.some | ||
case "error" => Level.Error.some | ||
case _ => None | ||
}) | ||
|
||
implicit val logFormatterDecoder: ConfigDecoder[String, Formatter] = | ||
ConfigDecoder[String, String].mapOption("Formatter")(_.toLowerCase match { | ||
case "default" => Formatter.default.some | ||
case "colorful" => Formatter.colorful.some | ||
case "json" => JFormatter.json.some | ||
case _ => None | ||
}) | ||
|
||
private val loggerConfig: ConfigValue[LoggerConfig] = ( | ||
env("LOG_LEVEL").as[Level].default(Level.Info), | ||
env("LOG_FORMATTER").as[Formatter].default(Formatter.colorful) | ||
).parMapN(LoggerConfig) | ||
|
||
private val apiDocsConfig: ConfigValue[ApiDocsConfig] = ( | ||
env("APIDOCS_SERVER_URL").as[ServerUrl].default("http://localhost:8080"), | ||
env("APIDOCS_DESCRIPTION").option | ||
).parMapN(ApiDocsConfig) | ||
|
||
private val serverConfig: ConfigValue[ServerConfig] = ( | ||
env("PORT").as[PortNumber].default(8080), | ||
apiDocsConfig | ||
).parMapN(ServerConfig) | ||
|
||
val config: ConfigValue[Config] = ( | ||
serverConfig, | ||
loggerConfig | ||
).parMapN(Config) | ||
} |
This file contains 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,46 @@ | ||
package app | ||
|
||
import scala.concurrent.ExecutionContext.global | ||
|
||
import cats.effect.{Resource, _} | ||
import cats.implicits._ | ||
import dev.usommerl.BuildInfo | ||
import eu.timepit.refined.auto._ | ||
import io.odin._ | ||
import org.http4s.server.{middleware, Server} | ||
import org.http4s.server.blaze.BlazeServerBuilder | ||
|
||
object Main extends IOApp { | ||
|
||
def run(args: List[String]): IO[ExitCode] = | ||
runF[IO].use(_ => IO.never) | ||
|
||
private def runF[F[_]: ContextShift: ConcurrentEffect: Timer]: Resource[F, Unit] = | ||
for { | ||
config <- app.config.resource[F] | ||
logger <- createLogger[F](config.logger) | ||
_ <- Resource.eval(logger.info(startMessage)) | ||
_ <- serve[F](config.server) | ||
} yield () | ||
|
||
private def createLogger[F[_]: ConcurrentEffect: Timer](config: LoggerConfig): Resource[F, Logger[F]] = | ||
Resource | ||
.pure[F, Logger[F]](consoleLogger[F](config.formatter, config.level)) | ||
.evalTap(logger => Sync[F].delay(OdinInterop.globalLogger.set(logger.mapK(Effect.toIOK).some))) | ||
|
||
private def serve[F[_]: ContextShift: ConcurrentEffect: Timer](config: ServerConfig): Resource[F, Server[F]] = | ||
BlazeServerBuilder[F](global) | ||
.bindHttp(config.port, "0.0.0.0") | ||
.withHttpApp(middleware.Logger.httpApp(logHeaders = true, logBody = false)(Api[F](config.apiDocs))) | ||
.resource | ||
|
||
private lazy val startMessage: String = | ||
"STARTED [ name: %s, version: %s, vmVersion: %s, scalaVersion: %s, sbtVersion: %s, builtAt: %s ]".format( | ||
BuildInfo.name, | ||
BuildInfo.version, | ||
System.getProperty("java.vm.version"), | ||
BuildInfo.scalaVersion, | ||
BuildInfo.sbtVersion, | ||
BuildInfo.builtAtString | ||
) | ||
} |
This file contains 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,26 @@ | ||
package app | ||
|
||
import java.util.concurrent.atomic.AtomicReference | ||
|
||
import cats.effect.Clock | ||
import cats.effect.Effect | ||
import cats.effect.IO | ||
import io.odin.Logger | ||
import io.odin.slf4j.OdinLoggerBinder | ||
|
||
/** This implementation was stolen from here: | ||
* https://github.com/pitgull/pitgull/blob/v0.0.7/src/main/scala/io/pg/OdinInterop.scala | ||
*/ | ||
class OdinInterop extends OdinLoggerBinder[IO] { | ||
implicit val F: Effect[IO] = IO.ioEffect | ||
implicit val clock: Clock[IO] = Clock.create[IO] | ||
|
||
val loggers: PartialFunction[String, Logger[IO]] = { | ||
val theLogger: String => Option[Logger[IO]] = _ => OdinInterop.globalLogger.get() | ||
theLogger.unlift | ||
} | ||
} | ||
|
||
object OdinInterop { | ||
val globalLogger = new AtomicReference[Option[Logger[IO]]](None) | ||
} |
This file contains 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 |
---|---|---|
@@ -1,33 +1,8 @@ | ||
package org.slf4j.impl | ||
|
||
import scala.concurrent.ExecutionContext | ||
|
||
import cats.effect.{Clock, Effect, IO, Timer} | ||
import io.odin.{consoleLogger, Level, Logger} | ||
import io.odin.formatter.Formatter | ||
import io.odin.slf4j.OdinLoggerBinder | ||
|
||
/** This is bridge is needed for project dependencies that require an SLF4J API | ||
* See: https://github.com/valskalla/odin/tree/v0.9.1#slf4j-bridge | ||
* | ||
* This particular implementation was stolen from here: | ||
* https://github.com/pitgull/pitgull/blob/v0.0.2/src/main/scala/org/slf4j/impl/StaticLoggerBinder.scala | ||
*/ | ||
class StaticLoggerBinder extends OdinLoggerBinder[IO] { | ||
implicit val F: Effect[IO] = IO.ioEffect | ||
implicit val clock: Clock[IO] = Clock.create[IO] | ||
|
||
import StaticLoggerBinder.baseLogger | ||
|
||
val loggers: PartialFunction[String, Logger[IO]] = { case _ => | ||
baseLogger.withMinimalLevel(Level.Info) | ||
} | ||
} | ||
class StaticLoggerBinder extends app.OdinInterop | ||
|
||
object StaticLoggerBinder extends StaticLoggerBinder { | ||
//EC isn't used - only Clock is required | ||
implicit val timer: Timer[IO] = IO.timer(ExecutionContext.parasitic) | ||
val baseLogger = consoleLogger[IO](formatter = Formatter.colorful) | ||
val REQUESTED_API_VERSION: String = "1.7" | ||
def getSingleton: StaticLoggerBinder = this | ||
} |
Oops, something went wrong.