Created
August 10, 2018 09:34
-
-
Save linsea/f7f7518016b17e4a0c79801b62854a0a to your computer and use it in GitHub Desktop.
Log分析统计脚本
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 java.io.File | |
import java.lang.System.exit | |
import java.text.SimpleDateFormat | |
import java.util.* | |
if (args.size != 3) { | |
println("使用方法: kotlinc -script logst.kts <input_log_file_path> <output_file_path> <regex_pattern>") | |
println("注意 <regex_pattern> 中的正则使用'|'分隔重点LOG行, 第一个和最后一个必须为一次统计的开始行和结束行正则, 否则无法分辨一次统计的起始点与终止点") | |
exit(1) | |
} | |
Loge(logFilePath = args[0], outputFilePath = args[1], regex = args[2]).execute() | |
class Loge(logFilePath: String, outputFilePath: String, val regex: String) { | |
private val logFile = File(logFilePath) | |
private val outputFile = File(outputFilePath) | |
private val regexList = regex.split("""|""").toList() | |
private val resultList = mutableListOf<MutableList<Element>>() | |
private var foundFirst = false | |
private var statis: MutableList<Element>? = null | |
private val dateFormat = SimpleDateFormat("HH:mm:ss.SSS") | |
fun execute() { | |
regexFind() | |
outputResult() | |
} | |
private fun extractDate(lineStr: String): Date { | |
val datetimeStr = lineStr.substring(0, 12) | |
return dateFormat.parse(datetimeStr) | |
} | |
private fun regexFind() { | |
val lines = logFile.readLines(Charsets.UTF_8) | |
lines.forEach { lineStr -> | |
if (lineStr.isNotEmpty()) { | |
regexList.forEachIndexed { idx, regStr -> | |
if (regStr.toRegex().containsMatchIn(lineStr)) { | |
if (idx == 0) { | |
foundFirst = true | |
statis = mutableListOf(Element(0, 0, extractDate(lineStr), lineStr, idx, null)) | |
} else if (idx == regexList.lastIndex) { | |
if (foundFirst) { | |
statis?.also { | |
it.add(Element(0, 0, extractDate(lineStr), lineStr, idx, null)) | |
resultList.add(it) | |
foundFirst = false | |
} | |
} | |
} else { | |
if (foundFirst) {//第一次匹配到的不是一次统计的日志开始点 | |
val matchedElement = Element(0, 0, extractDate(lineStr), lineStr, idx, null) | |
statis!!.add(matchedElement) | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
private fun outputResult() { | |
resultList.forEach { innerList -> | |
innerList.forEachIndexed { idx, el -> | |
if (idx != 0) { | |
val pre = innerList[idx - 1] | |
el.execTime = el.time.time - pre.time.time | |
el.elapseTime = el.time.time - innerList[0].time.time | |
} else { | |
outputHeader() | |
} | |
outputContent(el.format()) | |
} | |
} | |
outputAvg(resultList) | |
outputFooter() | |
} | |
private fun outputAvg(resultList: MutableList<MutableList<Element>>) { | |
var size = -1 | |
resultList.forEachIndexed { idx, innerList -> //检查每个size是否相等 | |
if (idx == 0) { | |
size = innerList.size | |
} else { | |
if (size == -1 || size != innerList.size) { | |
outputContent("=======================================================================") | |
outputContent("第${idx+1}次统计时匹配到的所有行数与前一次不相等,无法计算平均值!请检查正则或自行查看筛选出的日志.") | |
return | |
} | |
} | |
} | |
for (i in 0 until size) { //检查所有统计的每一行匹配的正则是否相等 | |
val regIdx = resultList[0][i].matchedRegIdx | |
resultList.forEachIndexed { index, innerList -> | |
if (index != 0) { | |
if (innerList[i].matchedRegIdx != regIdx) { | |
outputContent("=======================================================================") | |
outputContent("第${i+1}次,有行匹配到相同的正则,但与前一次的内容不同,无法计算平均值!请检查正则或自行查看筛选出的日志.") | |
outputContent("匹配到的日志:${innerList[i].log}") | |
outputContent("使用的正则表达式:${regexList[innerList[i].matchedRegIdx]}") | |
return | |
} | |
} | |
} | |
} | |
outputContent("==========================================") | |
outputContent("平均 Exec ms | 平均 Elapse ms | 样例LOG") | |
for (i in 0 until size) { | |
var avgExecTime: Long = 0 | |
var avgElapseTime: Long = 0 | |
var sampleLog: String? = "" | |
resultList.forEach { | |
avgExecTime += it[i].execTime!! | |
avgElapseTime += it[i].elapseTime!! | |
sampleLog = it[i].log | |
} | |
avgExecTime /= resultList.size | |
avgElapseTime /= resultList.size | |
outputContent(String.format("%12d | %15d | %s", avgExecTime, avgElapseTime, sampleLog)) | |
} | |
} | |
private fun outputHeader() { | |
outputContent("=================================") | |
outputContent("Exec ms | Elapse ms | Log Message") | |
outputContent("=================================") | |
} | |
private fun outputContent(s: String) { | |
println(s) | |
outputFile.appendText(s) | |
outputFile.appendText("\n") | |
} | |
private fun outputFooter() { | |
outputContent("=================================") | |
outputContent(" Regex: $regex ") | |
outputContent("Input Log File: ${logFile.absolutePath} ") | |
outputContent(" Output File: ${outputFile.absolutePath}") | |
outputContent("Output Success!") | |
} | |
} | |
data class Element( | |
var execTime: Long?, | |
var elapseTime: Long?, | |
val time: Date, | |
var log: String?, | |
var matchedRegIdx: Int, | |
var desc: String?) { | |
fun format(): String { | |
return String.format("%7d | %6d | %s", execTime, elapseTime, log) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment