Outil pour extraire des traces de pile java à partir de fichiers journaux [fermé]

Existe-t-il un outil qui peut extraire une liste de traces de pile apparaissant dans le fichier journal et probablement compter les traces uniques?

EDIT : Je preffer quelque chose qui n'est pas basé sur L'interface graphique et être exécuté en arrière-plan et donner une sorte de rapport. J'ai beaucoup de journaux rassemblés à partir de plusieurs environnements et je voudrais juste obtenir un aperçu rapide.

22
demandé sur Andrey Adamovich 2011-05-24 12:31:35

6 réponses

Voici une expression grep rapide et sale... si vous utilisez un enregistreur tel que log4j, la première ligne de l'exception contiendra généralement WARN ou ERROR, la ligne suivante contiendra le nom de L'Exception et éventuellement un message, puis la trace de pile suivante commencera par l'une des opérations suivantes:

  1. "\tat" (tab + at)
  2. "Caused by: "
  3. "\t... <some number> more" (ce sont les lignes qui indiquent le nombre d'images dans la pile non représenté dans un " causé par" exception)
  4. un nom D'Exception (et peut-être un message) avant la pile

Nous voulons obtenir toutes les lignes ci-dessus, donc l'expression grep est:

grep -P "(WARN|ERROR|^\tat |Exception|^Caused by: |\t... \d+ more)"

Il suppose qu'une classe D'Exception contient toujours le mot Exception qui peut ou non être vrai, mais c'est rapide et sale après tout.

Ajuster au besoin pour votre cas spécifique.

14
répondu Raman 2013-04-19 14:40:31

Vous pouvez écrire cela vous-même assez facilement. Voici le modèle:

  1. Ouvrir le fichier
  2. recherchez la chaîne "\n\tat " (c'est une nouvelle ligne, tab, at, vide) c'est une chaîne assez rare en dehors des traces de pile.

Maintenant tout ce que vous devez faire est de trouver la première ligne qui ne commence pas avec \t pour trouver la fin de la trace de la pile. Vous pouvez ignorer 1-3 lignes après cela pour attraper les exceptions enchaînées.

Plus ajoutez quelques lignes (disons 10 ou 50) avant première ligne de la trace de la pile pour obtenir du contexte.

13
répondu Aaron Digulla 2011-05-24 09:06:27

J'ai écrit un outil en Python. Il parvient à diviser deux traces de pile même si elles viennent juste après l'autre dans le journal.

#!/usr/bin/env python
#
# Extracts exceptions from log files.
#

import sys
import re
from collections import defaultdict

REGEX = re.compile("(^\tat |^Caused by: |^\t... \\d+ more)")
# Usually, all inner lines of a stack trace will be "at" or "Caused by" lines.
# With one exception: the line following a "nested exception is" line does not
# follow that convention. Due to that, this line is handled separately.
CONT = re.compile("; nested exception is: *$")

exceptions = defaultdict(int)

def registerException(exc):
  exceptions[exc] += 1

def processFile(fileName):
  with open(fileName, "r") as fh:
    currentMatch = None
    lastLine = None
    addNextLine = False
    for line in fh.readlines():
      if addNextLine and currentMatch != None:
        addNextLine = False
        currentMatch += line
        continue
      match = REGEX.search(line) != None
      if match and currentMatch != None:
        currentMatch += line
      elif match:
        currentMatch = lastLine + line
      else:
        if currentMatch != None:
          registerException(currentMatch)
        currentMatch = None
      lastLine = line
      addNextLine = CONT.search(line) != None
    # If last line in file was a stack trace
    if currentMatch != None:
      registerException(currentMatch)

for f in sys.argv[1:]:
  processFile(f)

for item in sorted(exceptions.items(), key=lambda e: e[1], reverse=True):
  print item[1], ":", item[0]
10
répondu daniel kullmann 2013-04-23 09:11:37

Je suis venu avec le script Groovy suivant. Il est, bien sûr, très adapté à mes besoins, mais j'espère qu'il aide quelqu'un.

def traceMap = [:]

// Number of lines to keep in buffer
def BUFFER_SIZE = 100

// Pattern for stack trace line
def TRACE_LINE_PATTERN = '^[\\s\\t]+at .*$'

// Log line pattern between which we try to capture full trace
def LOG_LINE_PATTERN = '^([<#][^/]|\\d\\d).*$'

// List of patterns to replace in final captured stack trace line 
// (e.g. replace date and transaction information that may make similar traces to look as different)
def REPLACE_PATTERNS = [
  '^\\d+-\\d+\\@.*?tksId: [^\\]]+\\]',
  '^<\\w+ \\d+, \\d+ [^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <',
  '^####<[^>]+?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <',
  '<([\\w:]+)?TransaktionsID>[^<]+?</([\\w:]+)?TransaktionsID>',
  '<([\\w:]+)?TransaktionsTid>[^<]+?</([\\w:]+)?TransaktionsTid>'
]

new File('.').eachFile { File file ->
  if (file.name.contains('.log') || file.name.contains('.out')) {
    def bufferLines = []
    file.withReader { Reader reader ->
      while (reader.ready()) {      
        def String line = reader.readLine()
        if (line.matches(TRACE_LINE_PATTERN)) {
          def trace = []
          for(def i = bufferLines.size() - 1; i >= 0; i--) {
            if (!bufferLines[i].matches(LOG_LINE_PATTERN)) {
              trace.add(0, bufferLines[i])
            } else {
              trace.add(0, bufferLines[i])
              break
            }
          }
          trace.add(line)
          if (reader.ready()) {
            line = reader.readLine()
            while (!line.matches(LOG_LINE_PATTERN)) {
              trace.add(line)
              if (reader.ready()) {
                line = reader.readLine()
              } else {
                break;
              }
            }
          }
          def traceString = trace.join("\n")
          REPLACE_PATTERNS.each { pattern ->
            traceString = traceString.replaceAll(pattern, '')
          }
          if (traceMap.containsKey(traceString)) {
            traceMap.put(traceString, traceMap.get(traceString) + 1)
          } else {
            traceMap.put(traceString, 1)
          }
        }
        // Keep the buffer of last lines.
        bufferLines.add(line)
        if (bufferLines.size() > BUFFER_SIZE) {
          bufferLines.remove(0)
        }
      }
    }
  }
}

traceMap = traceMap.sort { it.value }

traceMap.reverseEach { trace, number ->
  println "-- Occured $number times -----------------------------------------"
  println trace
}
2
répondu Andrey Adamovich 2011-05-26 14:41:32

Voici un bon code qui fait la même chose - http://www.techiedelight.com/java-program-search-exceptions-huge-log-file-on-server/

Il lit essentiellement le fichier journal ligne par ligne et recherche le mot-clé "Exception" dans chaque ligne. Une fois trouvé, il imprimera les 10 lignes suivantes (trace d'exception) dans un fichier de sortie séparé.

1
répondu Ani 2017-05-08 21:48:28

J'utilise Baretail.

0
répondu Rudy 2011-05-24 08:53:00