String search in file . log in Java

Asked

Viewed 71 times

1

I need to create a program where I can search a file . log and can find certain strings in it, for example:

Network path not found.

Among others that would represent errors in this log file, they are the ones I want to find.

Any idea how to do this simply?

  • Hello Matheus, what you tried, can share your code?

  • 1

    What is the format of LOG? After all there is no universal standard format for all logs.

  • It is a Windows Robocopy log file, understand as a normal . txt file. I tried some things I found on the internet, but I didn’t save any because I thought I’d take an idea from scratch and build a zero code, specific for what I need.

  • But the log was created by you or another program ?

  • The log is created by Windows Robocopy: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy

2 answers

1

You can get a Stream<String> that matches the file lines using File.lines(Path) (Java 8 or higher).

Your code should look like this:

File.lines(Paths.get("seu_arquivo.log"))
        .filter(x -> x.contains("O caminho de rede não foi encontrado."))
        .forEach(System.out::println);

If you want to put the line number together:

AtomicInteger a = new AtomicInteger(0);
File.lines(Paths.get("seu_arquivo.log"))
        .map(linha -> a.incrementAndGet() + "|" + linha)
        .filter(x -> x.contains("O caminho de rede não foi encontrado."))
        .forEach(System.out::println);

This assumes that your encoding is UTF-8. If it is ISO-8859-1 or some other, use the method lines overloaded who also receives a Charset:

File.lines(Paths.get("seu_arquivo.log"), StandardCharsets.ISO_8859_1)
  • Because the AtomicInteger ? the lines and/or map is parallelized in Threads different ?

  • @Isac No, it’s not parallelized. Actually it’s because if I use a variable like int, compiler would complain because I can’t change the value of variables that are not final effect inside both planes. An alternative would be to use a int[1], but that’s a very ugly gambiarra that I don’t like teaching others to do. An instance of a local class changeable just for that is kind of a Overkill and is another gambiarra. Already the AtomicInteger is the solution I consider to be the cleanest.

  • Okay, I didn’t remember that detail. When types are references they usually take the final which in that case does not serve.

0

For now the code I was able to create is getting like this, the result shows 3 values with "The network path was not found" contained in this example log, but this was just to learn, how would I add more occurrences to this program? I have at least 5 or more different codes that I would like it to display as well, the main idea is to link the occurrence of these error messages to the triggering of a sendmail, indicating that some problem occurred in a given backup and deserves extra attention.

public static void main(String args[]) {

    String fileName = "C:\\users\\Matheus\\desktop\\backup_outlook.log";
    List<String> list = new ArrayList<>();

    try (Stream<String> stream = Files.lines(Paths.get(fileName),StandardCharsets.ISO_8859_1)) {

                list = stream
                        .filter(line -> line.startsWith("O caminho da rede"))
                        .collect(Collectors.toList());

    } catch (IOException e) {
        e.printStackTrace();
    }

    list.forEach(System.out::println);

}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.