Skip to content

Instantly share code, notes, and snippets.

@dwijnand
Created November 27, 2014 03:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwijnand/be17d527ae25fd2318c4 to your computer and use it in GitHub Desktop.
Save dwijnand/be17d527ae25fd2318c4 to your computer and use it in GitHub Desktop.
import java.io.{ByteArrayOutputStream, PrintStream}
import java.security.MessageDigest
/** Identifies throwables by creating checksums (like MD5 or SHA1) of its stacktrace. */
object ErrId {
/** Returns the absolute checksum of the specified throwable. */
def absolute(t: Throwable): String = {
val bytes = stackBytes(t)
val md = sha1er
md update bytes
val digest = md.digest
hex(digest)
}
/** Returns the relative checksum of the specified throwable. */
def relative(t: Throwable): String = {
val caller = Thread.currentThread().getStackTrace()(2)
val relativeTrace = t.getStackTrace takeWhile { ste ⇒
ste.getClassName != caller.getClassName && ste.getMethodName != caller.getMethodName
}
val bytes = relativeTrace flatMap (_.toString getBytes "UTF-8")
val causeBytes = Option(t.getCause) map stackBytes
val md = sha1er
md update bytes
causeBytes foreach md.update
val digest = md.digest
hex(digest)
}
private def sha1er = MessageDigest getInstance "SHA-1"
private def stackBytes(t: Throwable): Array[Byte] = {
val out = new ByteArrayOutputStream()
t printStackTrace new PrintStream(out)
out.toByteArray
}
/** Returns the hexadecimal string form of the specified byte array. */
private def hex(bytes: Array[Byte]) = {
bytes map { b ⇒
val s = Integer toHexString 0xff & b
if (s.length == 1) s"0$s" else s
} mkString ""
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment