Utility to replace jvm and host:port with role in logs, see 2173

This commit is contained in:
Patrik Nordwall 2012-06-04 08:49:05 +02:00
parent ebc919ba61
commit 3c7ade3cdb
2 changed files with 151 additions and 0 deletions

View file

@ -0,0 +1,148 @@
package akka.remote.testkit
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.ClipboardOwner
import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.StringSelection
import java.awt.datatransfer.Transferable
import java.io.BufferedReader
import java.io.FileReader
import java.io.FileWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.io.PrintWriter
import java.io.StringReader
import java.io.StringWriter
import scala.annotation.tailrec
/**
* Utility to make log files from multi-node tests easier to analyze.
* Replaces jvm names and host:port with corresponding logical role name.
*/
object LogRoleReplace extends ClipboardOwner {
/**
* Main program. Use with 0, 1 or 2 arguments.
*
* When using 0 arguments it reads from standard input
* (System.in) and writes to standard output (System.out).
*
* With 1 argument it reads from the file specified in the first argument
* and writes to standard output.
*
* With 2 arguments it reads the file specified in the first argument
* and writes to the file specified in the second argument.
*
* You can also replace the contents of the clipboard instead of using files
* by supplying `clipboard` as argument
*/
def main(args: Array[String]): Unit = {
val replacer = new LogRoleReplace
if (args.length == 0) {
replacer.process(
new BufferedReader(new InputStreamReader(System.in)),
new PrintWriter(new OutputStreamWriter(System.out)))
} else if (args(0) == "clipboard") {
val clipboard = Toolkit.getDefaultToolkit.getSystemClipboard
val contents = clipboard.getContents(null)
if (contents != null && contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
val text = contents.getTransferData(DataFlavor.stringFlavor).asInstanceOf[String]
val result = new StringWriter
replacer.process(
new BufferedReader(new StringReader(text)),
new PrintWriter(result))
clipboard.setContents(new StringSelection(result.toString), this)
println("Replaced clipboard contents")
}
} else if (args.length == 1) {
val inputFile = new BufferedReader(new FileReader(args(0)))
try {
replacer.process(
inputFile,
new PrintWriter(new OutputStreamWriter(System.out)))
} finally {
inputFile.close()
}
} else if (args.length == 2) {
val outputFile = new PrintWriter(new FileWriter(args(1)))
val inputFile = new BufferedReader(new FileReader(args(0)))
try {
replacer.process(inputFile, outputFile)
} finally {
outputFile.close()
inputFile.close()
}
}
}
/**
* Empty implementation of the ClipboardOwner interface
*/
def lostOwnership(clipboard: Clipboard, contents: Transferable): Unit = ()
}
class LogRoleReplace {
private val RoleStarted = """\[([\w\-]+)\].*Role \[([\w]+)\] started""".r
private val RemoteServerStarted = """\[([\w\-]+)\].*RemoteServerStarted@akka://.*@([\w\-\.]+):([0-9]+)""".r
private var replacements: Map[String, String] = Map.empty
private var jvmToAddress: Map[String, String] = Map.empty
def process(in: BufferedReader, out: PrintWriter): Unit = {
@tailrec
def processLines(line: String): Unit = if (line ne null) {
out.println(processLine(line))
processLines(in.readLine)
}
processLines(in.readLine())
}
def processLine(line: String): String = {
if (updateReplacements(line))
replaceLine(line)
else
line
}
private def updateReplacements(line: String): Boolean = {
if (line.startsWith("[info] * ")) {
// reset when new test begins
replacements = Map.empty
jvmToAddress = Map.empty
}
line match {
case RemoteServerStarted(jvm, host, port)
jvmToAddress += (jvm -> (host + ":" + port))
false
case RoleStarted(jvm, role)
jvmToAddress.get(jvm) match {
case Some(address)
replacements += (jvm -> role)
replacements += (address -> role)
false
case None false
}
case _ true
}
}
private def replaceLine(line: String): String = {
var result = line
for ((from, to) replacements) {
result = result.replaceAll(from, to)
}
result
}
}

View file

@ -249,4 +249,7 @@ abstract class MultiNodeSpec(val myself: RoleName, _system: ActorSystem, roles:
}
}
// useful to see which jvm is running which role
log.info("Role [{}] started", myself.name)
}