mirror of https://github.com/sbt/sbt.git
Merge pull request #85 from eed3si9n/wip/crashlog
send TraceEvent on crash
This commit is contained in:
commit
a99a99ce43
15
build.sbt
15
build.sbt
|
|
@ -2,7 +2,7 @@ import Dependencies._
|
|||
import Util._
|
||||
// import com.typesafe.tools.mima.core._, ProblemFilters._
|
||||
|
||||
def baseVersion: String = "1.0.0-M24"
|
||||
def baseVersion = "1.0.0-SNAPSHOT"
|
||||
def internalPath = file("internal")
|
||||
|
||||
def commonSettings: Seq[Setting[_]] = Seq(
|
||||
|
|
@ -39,6 +39,11 @@ lazy val utilRoot: Project = (project in file(".")).
|
|||
settings(
|
||||
inThisBuild(Seq(
|
||||
git.baseVersion := baseVersion,
|
||||
version := {
|
||||
val v = version.value
|
||||
if (v contains "SNAPSHOT") git.baseVersion.value
|
||||
else v
|
||||
},
|
||||
bintrayPackage := "util",
|
||||
homepage := Some(url("https://github.com/sbt/util")),
|
||||
description := "Util module for sbt",
|
||||
|
|
@ -108,7 +113,13 @@ lazy val utilLogging = (project in internalPath / "util-logging").
|
|||
crossScalaVersions := Seq(scala210, scala211, scala212),
|
||||
name := "Util Logging",
|
||||
libraryDependencies ++= Seq(jline, log4jApi, log4jCore, disruptor, sjsonnewScalaJson, scalaReflect.value),
|
||||
sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala"
|
||||
sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala",
|
||||
contrabandFormatsForType in generateContrabands in Compile := { tpe =>
|
||||
val old = (contrabandFormatsForType in generateContrabands in Compile).value
|
||||
val name = tpe.removeTypeParameters.name
|
||||
if (name == "Throwable") Nil
|
||||
else old(tpe)
|
||||
},
|
||||
)
|
||||
|
||||
// Relation
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ abstract class AbstractEntry(
|
|||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (17 + channelName.##) + execId.##)
|
||||
37 * (37 * (37 * (17 + "AbstractEntry".##) + channelName.##) + execId.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"AbstractEntry(" + channelName + ", " + execId + ")"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ final class StringEvent private (
|
|||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (17 + level.##) + message.##) + channelName.##) + execId.##)
|
||||
37 * (37 * (37 * (37 * (37 * (17 + "StringEvent".##) + level.##) + message.##) + channelName.##) + execId.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"StringEvent(" + level + ", " + message + ", " + channelName + ", " + execId + ")"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.util
|
||||
final class TraceEvent private (
|
||||
val level: String,
|
||||
val message: Throwable,
|
||||
channelName: Option[String],
|
||||
execId: Option[String]) extends sbt.internal.util.AbstractEntry(channelName, execId) with Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: TraceEvent => (this.level == x.level) && (this.message == x.message) && (this.channelName == x.channelName) && (this.execId == x.execId)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (37 * (17 + "TraceEvent".##) + level.##) + message.##) + channelName.##) + execId.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"TraceEvent(" + level + ", " + message + ", " + channelName + ", " + execId + ")"
|
||||
}
|
||||
protected[this] def copy(level: String = level, message: Throwable = message, channelName: Option[String] = channelName, execId: Option[String] = execId): TraceEvent = {
|
||||
new TraceEvent(level, message, channelName, execId)
|
||||
}
|
||||
def withLevel(level: String): TraceEvent = {
|
||||
copy(level = level)
|
||||
}
|
||||
def withMessage(message: Throwable): TraceEvent = {
|
||||
copy(message = message)
|
||||
}
|
||||
def withChannelName(channelName: Option[String]): TraceEvent = {
|
||||
copy(channelName = channelName)
|
||||
}
|
||||
def withChannelName(channelName: String): TraceEvent = {
|
||||
copy(channelName = Option(channelName))
|
||||
}
|
||||
def withExecId(execId: Option[String]): TraceEvent = {
|
||||
copy(execId = execId)
|
||||
}
|
||||
def withExecId(execId: String): TraceEvent = {
|
||||
copy(execId = Option(execId))
|
||||
}
|
||||
}
|
||||
object TraceEvent {
|
||||
|
||||
def apply(level: String, message: Throwable, channelName: Option[String], execId: Option[String]): TraceEvent = new TraceEvent(level, message, channelName, execId)
|
||||
def apply(level: String, message: Throwable, channelName: String, execId: String): TraceEvent = new TraceEvent(level, message, Option(channelName), Option(execId))
|
||||
}
|
||||
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.util.codec
|
||||
import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder }
|
||||
trait AbstractEntryFormats { self: sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.StringEventFormats =>
|
||||
implicit lazy val AbstractEntryFormat: JsonFormat[sbt.internal.util.AbstractEntry] = flatUnionFormat1[sbt.internal.util.AbstractEntry, sbt.internal.util.StringEvent]("type")
|
||||
|
||||
import _root_.sjsonnew.JsonFormat
|
||||
trait AbstractEntryFormats { self: sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.StringEventFormats with sbt.internal.util.codec.TraceEventFormats =>
|
||||
implicit lazy val AbstractEntryFormat: JsonFormat[sbt.internal.util.AbstractEntry] = flatUnionFormat2[sbt.internal.util.AbstractEntry, sbt.internal.util.StringEvent, sbt.internal.util.TraceEvent]("type")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@
|
|||
package sbt.internal.util.codec
|
||||
trait JsonProtocol extends sjsonnew.BasicJsonProtocol
|
||||
with sbt.internal.util.codec.StringEventFormats
|
||||
with sbt.internal.util.codec.TraceEventFormats
|
||||
with sbt.internal.util.codec.AbstractEntryFormats
|
||||
object JsonProtocol extends JsonProtocol
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.util.codec
|
||||
import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder }
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait StringEventFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val StringEventFormat: JsonFormat[sbt.internal.util.StringEvent] = new JsonFormat[sbt.internal.util.StringEvent] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.util.StringEvent = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.util.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait TraceEventFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val TraceEventFormat: JsonFormat[sbt.internal.util.TraceEvent] = new JsonFormat[sbt.internal.util.TraceEvent] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.util.TraceEvent = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val level = unbuilder.readField[String]("level")
|
||||
val message = unbuilder.readField[Throwable]("message")
|
||||
val channelName = unbuilder.readField[Option[String]]("channelName")
|
||||
val execId = unbuilder.readField[Option[String]]("execId")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.util.TraceEvent(level, message, channelName, execId)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.util.TraceEvent, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("level", obj.level)
|
||||
builder.addField("message", obj.message)
|
||||
builder.addField("channelName", obj.channelName)
|
||||
builder.addField("execId", obj.execId)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,3 +14,10 @@ type StringEvent implements sbt.internal.util.AbstractEntry {
|
|||
channelName: String
|
||||
execId: String
|
||||
}
|
||||
|
||||
type TraceEvent implements sbt.internal.util.AbstractEntry {
|
||||
level: String!
|
||||
message: Throwable!
|
||||
channelName: String
|
||||
execId: String
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package sbt.internal.util
|
||||
|
||||
import sbt.util._
|
||||
import org.apache.logging.log4j.{ Logger => XLogger }
|
||||
import org.apache.logging.log4j.{ Logger => XLogger, Level => XLevel }
|
||||
import org.apache.logging.log4j.message.ObjectMessage
|
||||
import sjsonnew.JsonFormat
|
||||
import scala.reflect.runtime.universe.TypeTag
|
||||
import sbt.internal.util.codec.ThrowableShowLines._
|
||||
import sbt.internal.util.codec.TraceEventShowLines._
|
||||
import sbt.internal.util.codec.JsonProtocol._
|
||||
|
||||
/**
|
||||
* Delegates log events to the associated LogExchange.
|
||||
|
|
@ -15,7 +18,8 @@ class ManagedLogger(
|
|||
val execId: Option[String],
|
||||
xlogger: XLogger
|
||||
) extends Logger {
|
||||
override def trace(t: => Throwable): Unit = () // exchange.appendLog(new Trace(t))
|
||||
override def trace(t: => Throwable): Unit =
|
||||
logEvent(Level.Error, TraceEvent("Error", t, channelName, execId))
|
||||
override def log(level: Level.Value, message: => String): Unit =
|
||||
{
|
||||
xlogger.log(
|
||||
|
|
@ -32,6 +36,8 @@ class ManagedLogger(
|
|||
// println(s"registerStringCodec ${tag.key}")
|
||||
val _ = LogExchange.getOrElseUpdateStringCodec(tag.key, ev)
|
||||
}
|
||||
registerStringCodec[Throwable]
|
||||
registerStringCodec[TraceEvent]
|
||||
final def debugEvent[A: JsonFormat: TypeTag](event: => A): Unit = logEvent(Level.Debug, event)
|
||||
final def infoEvent[A: JsonFormat: TypeTag](event: => A): Unit = logEvent(Level.Info, event)
|
||||
final def warnEvent[A: JsonFormat: TypeTag](event: => A): Unit = logEvent(Level.Warn, event)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ trait JValueFormats { self: sjsonnew.BasicJsonProtocol =>
|
|||
def read[J](j: Option[J], u: Unbuilder[J]) = JNull
|
||||
}
|
||||
|
||||
implicit val JBooleanFormat: JF[JBoolean] = project(_.get, (x: Boolean) => JBoolean(x))
|
||||
implicit val JStringFormat: JF[JString] = project(_.value, (x: String) => JString(x))
|
||||
implicit val JNumberFormat: JF[JNumber] = project(x => BigDecimal(x.value), (x: BigDecimal) => JNumber(x.toString))
|
||||
implicit val JArrayFormat: JF[JArray] = project[JArray, Array[JValue]](_.value, JArray(_))
|
||||
implicit val JBooleanFormat: JF[JBoolean] = projectFormat(_.get, (x: Boolean) => JBoolean(x))
|
||||
implicit val JStringFormat: JF[JString] = projectFormat(_.value, (x: String) => JString(x))
|
||||
implicit val JNumberFormat: JF[JNumber] = projectFormat(x => BigDecimal(x.value), (x: BigDecimal) => JNumber(x.toString))
|
||||
implicit val JArrayFormat: JF[JArray] = projectFormat[JArray, Array[JValue]](_.value, JArray(_))
|
||||
|
||||
implicit lazy val JObjectJsonWriter: JW[JObject] = new JW[JObject] {
|
||||
def write[J](x: JObject, b: Builder[J]) = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package sbt
|
||||
package internal.util.codec
|
||||
|
||||
import sbt.util.ShowLines
|
||||
import sbt.internal.util.{ StackTrace, TraceEvent }
|
||||
|
||||
trait ThrowableShowLines {
|
||||
implicit val sbtThrowableShowLines: ShowLines[Throwable] =
|
||||
ShowLines[Throwable]( (t: Throwable) => {
|
||||
// 0 means enabled with default behavior. See StackTrace.scala.
|
||||
val traceLevel = 0
|
||||
List(StackTrace.trimmed(t, traceLevel))
|
||||
})
|
||||
}
|
||||
|
||||
object ThrowableShowLines extends ThrowableShowLines
|
||||
|
||||
trait TraceEventShowLines {
|
||||
implicit val sbtTraceEventShowLines: ShowLines[TraceEvent] =
|
||||
ShowLines[TraceEvent]( (t: TraceEvent) => {
|
||||
ThrowableShowLines.sbtThrowableShowLines.showLines(t.message)
|
||||
})
|
||||
}
|
||||
|
||||
object TraceEventShowLines extends TraceEventShowLines
|
||||
|
|
@ -43,7 +43,7 @@ object Dependencies {
|
|||
val scalatest = "org.scalatest" %% "scalatest" % "3.0.1"
|
||||
val parserCombinator211 = "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4"
|
||||
|
||||
val sjsonnewVersion = "0.7.0"
|
||||
val sjsonnewVersion = "0.8.0-M1"
|
||||
val sjsonnew = "com.eed3si9n" %% "sjson-new-core" % sjsonnewVersion
|
||||
val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.4.0")
|
||||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0-M1")
|
||||
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3")
|
||||
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M5")
|
||||
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M6")
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ object FilesInfo {
|
|||
def empty[F <: FileInfo]: FilesInfo[F] = FilesInfo(Set.empty[F])
|
||||
|
||||
implicit def format[F <: FileInfo: JsonFormat]: JsonFormat[FilesInfo[F]] =
|
||||
project(_.files, (fs: Set[F]) => FilesInfo(fs))
|
||||
projectFormat(_.files, (fs: Set[F]) => FilesInfo(fs))
|
||||
|
||||
def full: FileInfo.Style = FileInfo.full
|
||||
def hash: FileInfo.Style = FileInfo.hash
|
||||
|
|
@ -52,7 +52,7 @@ object FileInfo {
|
|||
type F <: FileInfo
|
||||
|
||||
implicit def format: JsonFormat[F]
|
||||
implicit def formats: JsonFormat[FilesInfo[F]] = project(_.files, (fs: Set[F]) => FilesInfo(fs))
|
||||
implicit def formats: JsonFormat[FilesInfo[F]] = projectFormat(_.files, (fs: Set[F]) => FilesInfo(fs))
|
||||
|
||||
def apply(file: File): F
|
||||
def apply(files: Set[File]): FilesInfo[F] = FilesInfo(files map apply)
|
||||
|
|
|
|||
Loading…
Reference in New Issue