-
-
Save xuwei-k/5b8f1f924ff5c10eb30dcf9ad2fe5c03 to your computer and use it in GitHub Desktop.
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
package sbt // package privateなclassを参照したいので | |
import java.nio.file.Files | |
import sbt.internal.AbstractTaskExecuteProgress | |
import sbt.internal.ShutdownHooks | |
import scala.concurrent.duration._ | |
import sjsonnew.shaded.scalajson.ast.unsafe.JString | |
import sjsonnew.support.scalajson.unsafe.CompactPrinter | |
/** | |
* 本来sbtの起動時の引数に `-Dsbt.traces=true` だけ指定すれば、大体同等のことが可能だが、 | |
* デフォルトだと全てのtaskが記録されて大きなファイルになるので、多少改変したもの | |
* [[https://github.com/sbt/sbt/blob/eec3c32cc841365799eaa5460272e8287b975f10/main/src/main/scala/sbt/internal/TaskTraceEvent.scala]] | |
* [[https://github.com/sbt/sbt/pull/4576]] | |
*/ | |
class ChromeTraceEventReporter extends AbstractTaskExecuteProgress with ExecuteProgress[Task] { | |
import AbstractTaskExecuteProgress.Timer | |
private[this] val start = System.nanoTime | |
override def initial(): Unit = () | |
override def afterReady(task: Task[_]): Unit = () | |
override def afterCompleted[T](task: Task[T], result: Result[T]): Unit = () | |
override def afterAllCompleted(results: RMap[Task, Result]): Unit = () | |
override def stop(): Unit = () | |
ShutdownHooks.add(() => report()) | |
private[this] def report() = { | |
if (anyTimings) { | |
writeTraceEvent() | |
} | |
} | |
def taskFilter(name: String, durationMicros: Long): Boolean = { | |
// 一定以上時間がかかったものだけを記録 | |
durationMicros > 1.seconds.toMicros | |
} | |
private[this] def writeTraceEvent(): Unit = { | |
val fileName = "trace.json" | |
val tracesDirectory = (new File("target").getAbsoluteFile) / "traces" | |
if (!tracesDirectory.exists) IO.createDirectory(tracesDirectory) | |
else () | |
val outFile = tracesDirectory / fileName | |
val trace = Files.newBufferedWriter(outFile.toPath) | |
try { | |
trace.append("""{"traceEvents":[""") | |
trace.append("\n") | |
def durationEvent(name: String, t: Timer): String = { | |
val sb = new java.lang.StringBuilder(name.length + 2) | |
CompactPrinter.print(new JString(name), sb) | |
s"""{"name":${sb.toString},"cat":"","ph":"X","ts":${(t.startMicros)},"dur":${(t.durationMicros)},"pid":0,"tid":${t.threadId}}""" | |
} | |
val entryIterator = currentTimings | |
var first = true | |
while (entryIterator.hasNext) { | |
val (key, value) = entryIterator.next() | |
val n = taskName(key) | |
if (taskFilter(n, value.durationMicros)) { | |
if (first) { | |
first = false | |
} else { | |
trace.append(",\n") | |
} | |
trace.append(durationEvent(n, value)) | |
} | |
} | |
trace.append("\n]}\n") | |
() | |
} finally { | |
trace.close() | |
try println(s"wrote $outFile") | |
catch { case _: java.nio.channels.ClosedChannelException => } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment