我试图循环浏览一个日志(log)文本文件,其中包含SSH登录和其他日志(log).

程序正在返回SSH登录的总数.

我的解决方案确实有效,但似乎有点慢(在200mo文件中约3.5秒).我想知道是否有任何方法可以让它更快.我对Java的良好实践并不十分熟悉.

我用的是BufferedReader级.也许有更好的课程/方法,但我在网上找到的其他东西都比较慢.

{
            BufferedReader br;
            if(fileLocation != null) {
                br = new BufferedReader(new FileReader(fileLocation));
            }
            else {
                br = new BufferedReader((new InputStreamReader(System.in, "UTF-8")));
            }
            String line;
            Stack<String> users = new Stack<>();
            int succeeded = 0;
            int failed;
            int total = 0;

            if(!br.ready()) {
                help("Cannot read the file", true);
            }
            while((line=br.readLine())!=null)
            {
                if(!line.contains("sshd")) continue;
                String[] arr = line.split("\\s+");
                if(arr.length < 11) continue;


                String log = arr[4];
                String log2 = arr[5];
                String log3 = arr[8];
                String user = arr[10];
                if(!log.contains("sshd")) continue;
                if(!log2.contains("Accepted")) {
                    if(log3.contains("failure")) {
                        total++;
                    }
                    continue;
                }
                total++;
                succeeded++;

                if(!repeat) {
                    if (users.contains(user)) continue;
                    users.add(user);
                }

                System.out.println((total + 1) + " " + user);
            }

完整代码:https://pastebin.com/xp2P9wja

此外,以下是日志(log)文件的几行:

Dec  3 12:20:12 k332 sshd[25206]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=10.147.222.137 
Dec  3 12:20:14 k332 sshd[25204]: error: PAM: Authentication failure for illegal user admin from 10.147.222.137
Dec  3 12:20:14 k332 sshd[25204]: Failed keyboard-interactive/pam for invalid user admin from 10.147.222.137 port 36417 ssh2
Dec  3 12:20:14 k332 sshd[25204]: Connection closed by invalid user admin 10.147.222.137 port 36417 [preauth]
Dec  3 12:20:40 k332 sshd[25209]: pam_tally2(sshd:auth): Tally overflowed for user root

最终输出为:

Total :
103 unique IP SSH logins succeeded
30387 SSH logins succeeded
17186 SSH logins failed
47573 total SSH logins

谢谢你抽出时间!

编辑:Mo(兆字节)=MB(兆字节)(我们通常在法语中说Mo)

以下是所有人都需要的完整更新代码:https://pastebin.com/Kn5EqLNX

推荐答案

如果您获得了代码的配置文件,那么问题显然出在String.split()方法中:

enter image description here

这是标准Java库中的一个已知问题:Java split String performances.

所以为了加速你的代码,你需要以某种方式加速这部分代码.我可以建议的第一件事是用以下代码替换第75-79行的代码:

Pattern pattern = Pattern.compile("\\s+");
while ((line = br.readLine()) != null) {
    if (!line.contains("sshd")) continue;
    String[] arr = pattern.split(line);
    if (arr.length < 11) continue;
...
}

这可能会使代码速度加快一点,但您可以从概要文件中看到,在模式和匹配器方法上仍然花费了大量时间.我们需要摆脱模式和匹配器,以获得显著的加速.

对于单字符模式,split可以在不使用正则表达式的情况下工作,并且非常有效,让我们try 用以下代码替换代码:

while ((line = br.readLine()) != null) {
    if (!line.contains("sshd")) continue;
    String[] arr = Arrays.stream(line.split(" "))
                    .filter(s -> !s.isEmpty())
                    .toArray(String[]::new);
    if (arr.length < 11) continue;
...
}

这段代码在相同数据上的运行速度几乎是原来的两倍.

Java相关问答推荐

try Dockerize Maven应用程序,但发布版本21不支持"

Javascript更新alert 可扩展内容样式与CSS—按钮更多/更少

RichFaces 3.x-Spring Boot-迁移web.xml

使用PDFBox从PDF中删除图像

如何在Cosmos DB(Java SDK)中增加默认响应大小

try 从REST API返回对象列表时出错

在settings.gradle.kts和Build.gradle.kts中使用公共变量

JFree Chart从图表中删除边框

Java中HashSet的搜索时间与TreeSet的搜索时间

判断重复的两个二维表算法?

持续时间--为什么在秒为负数的情况下还要做额外的工作?

如何判断元素计数并在流的中间抛出异常?

Java编译器是否进行了持续的折叠优化,以及如何进行判断?

设置背景时缺少Android编辑文本下划线

无泄漏函数的Java DRY

如何从指定某些字段的父对象创建子对象

Spring Integration SFTP 连接失败 - 无法协商 kex 算法的密钥交换

Vaadin Flow:设置密码显示按钮属性

更新不可变的深层嵌套字段

在对象列表上调用提取后,如何判断没有值为空?