java - Splunk Java 与 JUnit 的集成

标签 java junit splunk

我制作了一个模块,可以让我使用 Java SDK 与 splunk 集成。我们通过 Maven 使用 1.2.1.0。

我的模块似乎运行良好。但是,我想围绕它进行 junit 单元测试。我创建了试图恢复最近事件的测试,但除非我睡大觉,否则我永远不会得到我刚刚输入的内容,通常是它之前的事件。我还通过索引上的事件计数(我使用测试索引)尝试了它,但也没有正确更新。有什么好的方法可以执行我可以实际验证和断言的 JUnit 测试吗?

我在这个应用程序中使用了 spring,所以我有一个单例服务来做这个日志记录。这是服务实现:

/*
 * Copyright (c) 2015 POS Portal, Inc.
 * 180 Promenade Circle, Ste 215, Sacramento, CA 95834, USA
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of POS Portal, Inc.
 * 
 */
package com.posportal.splunk.impl;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.posportal.splunk.api.SplunkLog;
import com.posportal.splunk.enumeration.SplunkLoggingLevel;
import com.splunk.Receiver;
import com.splunk.Service;
import com.splunk.ServiceArgs;

/**
 * Represents a splunk logging instance.  This is a spring singleton for logging. 
 * 
 * We log to the index given, so it is acceptable to have a singleton on a per index basis.  
 * 
 * Splunk configuration including index name are injected via Spring. 
 * @author Michael Wenk
 *
 */
public class SplunkLogImpl implements SplunkLog {
    private static Logger log = LoggerFactory.getLogger(SplunkLogImpl.class); 
    private String host;
    private String user;
    private String password;
    private String scheme;
    private String indexName;

    private int port;

    private boolean disabled = false; 

    private Service splunksvc = null;
    private Receiver receiver = null; 

    @Override
    public void logMessage(String msg, SplunkLoggingLevel level) {
        if (disabled) {
            log.warn("Splunk system disabled.  Splunk message would be: " + msg + " on level: " + level);
        } else {
            if (receiver == null) {
                initService();
            }
            String formattedMessageData = formatMessage(msg, level); 
            receiver.log(indexName, formattedMessageData);
        }
    }

    private String formatMessage(String msg, SplunkLoggingLevel level) {
        String fmt = "timestamp=\"%s\",level=\"%s\",data=\"%s\""; 
        Date now = new Date(); 
        return String.format(fmt, now.toString(), level.toString(), msg); 
    }

    private void initService() {
        ServiceArgs loginArgs = new ServiceArgs();
        loginArgs.setUsername(user);
        loginArgs.setPassword(password);
        loginArgs.setHost(host);
        loginArgs.setScheme(scheme);
        loginArgs.setPort(port);

        splunksvc = Service.connect(loginArgs);
        receiver = splunksvc.getReceiver(); 
    }

    public void setHost(String host) {
        this.host = host;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;       
    }

    @Override
    public boolean isDisabled() {
        return disabled;
    }
}

这是单元测试代码:

/*
 * Copyright (c) 2015 POS Portal, Inc.
 * 180 Promenade Circle, Ste 215, Sacramento, CA 95834, USA
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of POS Portal, Inc.
 * 
 */
package com.posportal.splunk.test;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.Map;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.posportal.splunk.api.SplunkLog;
import com.posportal.splunk.enumeration.SplunkLoggingLevel;
import com.splunk.Job;
import com.splunk.JobArgs;
import com.splunk.JobArgs.ExecutionMode;
import com.splunk.Service;
import com.splunk.ServiceArgs;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:pos-splunk-test-ctx.xml")
public class SplunkTest {
    //private static Logger log = LoggerFactory.getLogger(SplunkTest.class); 
    @Resource(name = "splunkLog")
    private SplunkLog splunk;

    @Resource(name = "splunkConfig")
    private Map<String,String> splunkConfig; 

    @Test
    public void testInitialMessage() throws InterruptedException
    {
        if (splunk.isDisabled())
        {
            String msg = "This is my test";
            splunk.logMessage(msg, SplunkLoggingLevel.INFO);
        }
        else
        {
            int startCount = getEventCountFromIndex(); 
            String msg = "This is my test";
            assertNotNull(splunk); 
            splunk.logMessage(msg, SplunkLoggingLevel.INFO);
            Service svc = getService(); 
            assertNotNull(svc); 
            // Sleep for a while. 
            Thread.sleep(4000);

            int finalCount = getEventCountFromIndex(); 


            assertTrue(finalCount > startCount); 

        }

    }

    @Test
    public void testDisabled() {
        if (!splunk.isDisabled())
        {
            splunk.setDisabled(true);
            splunk.logMessage("This is a disabled test", SplunkLoggingLevel.INFO);
            // Can't assert unfortunately, 
            //FIXME see if I can assert using log4j itself. 
        }
    }
    private int getEventCountFromIndex() {
        String searchString = "search index="+ splunkConfig.get("indexName");
        JobArgs jargs = new JobArgs();
        jargs.setExecutionMode(ExecutionMode.BLOCKING);
        Service svc = getService(); 
        Job j = svc.getJobs().create(searchString, jargs);
        return j != null ? j.getEventCount() : -1; 
    }
    @Test
    public void testSecondMessage() throws  InterruptedException
    {
        if (splunk.isDisabled())
        {
            String msg = "This is my second test";
            splunk.logMessage(msg, SplunkLoggingLevel.INFO);
        }
        else
        {
            int startCount = getEventCountFromIndex(); 
            String msg = "This is my second test";
            assertNotNull(splunk); 
            splunk.logMessage(msg, SplunkLoggingLevel.INFO);
            Service svc = getService(); 
            assertNotNull(svc); 
            // Sleep for a while. 
            Thread.sleep(4000);
            int finalCount = getEventCountFromIndex(); 
            assertTrue(finalCount > startCount); 
        }
    }


    private Service getService() {
        ServiceArgs loginArgs = new ServiceArgs();
        loginArgs.setUsername(splunkConfig.get("user"));
        loginArgs.setPassword(splunkConfig.get("password"));
        loginArgs.setHost(splunkConfig.get("host"));
        loginArgs.setScheme(splunkConfig.get("scheme"));
        int port = Integer.parseInt(splunkConfig.get("port"));
        loginArgs.setPort(port);
        Service service = Service.connect(loginArgs);
        return service;
    }

}

如果你注意到那里的 sleep 。如果我不 sleep ,索引中的事件数就不会增加。不幸的是,有时 4 秒是不够的。

最佳答案

您看到的时间延迟是 Splunk 索引事件,这涉及写入磁盘并且可能需要时间。正如您已经尝试过的那样,解决方案是等待 Splunk 完成。

我建议为您要尝试的次数设置一个上限,并每隔 x 秒( hibernate 时间)检查一次。

在 Splunk SDK for Java(参见 SearchJobTest.javaSDKTestCase.java)中,我们基本上使用 assertEventuallyTrue() 方法做同样的事情:

public static boolean assertEventuallyTrue(EventuallyTrueBehavior behavior) {
    int remainingTries = behavior.tries;
    while (remainingTries > 0) {
        boolean succeeded = behavior.predicate();
        if (succeeded) {
            return true;
        } else {
            remainingTries -= 1;
            try {
                Thread.sleep(behavior.pauseTime);
            } catch (InterruptedException e) {}
        }
    }
    Assert.fail(behavior.timeoutMessage);
    return false;
}

关于java - Splunk Java 与 JUnit 的集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28619336/

相关文章:

JUnit:无法模拟 RestTemplate 对象来调用 postForObject 方法

android - 在查看/解析 IIS 日志时,如何过滤掉来自移动应用程序而不是 Web 浏览器的对 API 的直接调用

java - 两个队列和不同的线程

java - Xpath - 为什么只返回 1 个值?

java - 如何用commons-exec执行/bin/sh?

spring-mvc - Spring-Integration-Splunk依赖问题

docker - 无法在 Kubernetes 上挂载 Splunk 配置 - 错误 : Couldn't read "/opt/splunk/etc/splunk-launch. conf

java - NameNotFoundException 将 JNDI 数据源映射到本地名称

unit-testing - 这些是我在使用单元测试时应该考虑的边缘情况吗?

java - cucumber Java 屏幕截图