Skip to content

Instantly share code, notes, and snippets.

@ppopoff
Last active December 11, 2015 00:43
Show Gist options
  • Save ppopoff/666b5e20f9623c898f39 to your computer and use it in GitHub Desktop.
Save ppopoff/666b5e20f9623c898f39 to your computer and use it in GitHub Desktop.
import scala.collection.JavaConverters._
import oi.thekraken.grok.api.Grok
/**
* keys that will be extracted from the grok Map
*/
object Keys {
val clientIp = "clientip"
val ident = "ident"
val auth = "auth"
val timeStamp = "timestamp"
val httpStatus = "httpstatus"
// composite 'response' field
val method = "httpmethod"
val request = "request"
val httpVersion = "httpversion"
val rawRequest = "rawrequest"
val responseBytes = "bytes"
}
/**
* Grok templates for future replacement
*/
object Templates {
import Keys._
val host = s"%{IPORHOST:$clientIp}"
val identifier = s"%{USER:$ident}"
val user = s"%{USER:$auth}"
val timestamp = s"\\[%{HTTPDATE:$timeStamp}\\]"
val response =
s"(?:%{WORD:$method} %{NOTSPACE:$request}(?: HTTP/%{NUMBER:$httpVersion})?|%{DATA:$rawRequest})"
val status = s"%{NUMBER:$httpStatus}"
val bytes = s"(?:%{NUMBER:$responseBytes}|-)"
/**
* Replacing data with grok pattern
*/
def applyTo(format: String): String = {
format.replaceAllLiterally("%h", host)
.replaceAllLiterally("%l", identifier)
.replaceAllLiterally("%u", user)
.replaceAllLiterally("%t", timestamp)
.replaceAllLiterally("%r", response)
// Use regexp to replace value with modifiers
.replaceAll("%[<>]?s", status)
.replaceAllLiterally("%b", bytes)
}
}
class Parser(logFormat: String) {
// replacing keys with corresponding patterns
lazy val preparedLogFormat = Templates applyTo logFormat
// Grok initialization
private val grok = Grok create "patterns"
grok compile preparedLogFormat
def parse(event: String) = {
// Some ugly code
val gm = grok `match` event
gm.captures()
val results = gm.toMap.asScala
for {
timestamp <- results get Keys.timeStamp
client <- results get Keys.clientIp
status <- results get Keys.httpStatus
request <- results get Keys.request
method <- results get Keys.method
}
yield (timestamp, client, request, method, status)
}
}
object Main {
def main(args: Array[String]): Unit = {
// initial log format [hardcoded]
val logFormat = "%h %l %u %t \"%r\" %>s %b"
// log event to parse
val event =
"""127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326"""
val parser = new Parser(logFormat)
println(parser parse event)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment