Last active
December 11, 2015 00:43
-
-
Save ppopoff/666b5e20f9623c898f39 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
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