为什么重复每个后续日志条目(使用java.util.logging)?

时间:2017-06-12 15:29:40

标签: java java.util.logging

我有一个测试,我想从测试中记录一些信息。我设法使用基本的java记录器,但我做错了。每个后续条目日志消息都会成倍增加,即。第一条消息记录一次,第二条消息记录两次,第三条消息记录三次等等,我不确定我做错了什么。消息也被推送到控制台,但只有一次。

public class MyExampleTest {
    private FileHandler fh = null;
    private static final Logger logger = Logger.getLogger(MyExampleTest.class.getName());
    SimpleFormatter formatter = new SimpleFormatter();

    @Test
    public void infoPackage() throws Exception {
        fh = new FileHandler("test.log", true);
        // do some test stuff
        writeEntryToLogFile("entry one");
        // do some more test stuff
        writeEntryToLogFile("entry two");
        // do even more test stuff
        writeEntryToLogFile("entry three");
    }

    private void writeEntryToLogFile(String message) throws Exception {
        fh.setFormatter(formatter); 
        logger.addHandler(fh);
        logger.info(message);
    }

}

我的日志文件最终如下:

entry one
entry two
entry two
entry three
entry three
entry three

我想我是在搞乱文件处理程序,但我不知道是什么。

5 个答案:

答案 0 :(得分:4)

每次调用@Before时都会添加一个处理程序 因此,每次调用都会有额外的重复输出。

您应该添加一个设置方法,为每个执行的测试设置上下文。
您正在使用的JUnit允许使用@Before public void setup() { fh = new FileHandler("test.log", true); formatter = new SimpleFormatter(); fh.setFormatter(formatter); logger.addHandler(fh); } 注释:

    @POST
    //@Path("/create")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createCustomers(@FormParam("firstname") String firstname,
                                    @FormParam("lastname") String lastname,
                                    @FormParam("email") String email,
                                    @FormParam("dateborn") String dateborn,
                                    @FormParam("pass") String pass,
                                    @Context UriInfo uriInf
    ){
        CustomersEntity customer = new CustomersEntity();
        customer.setFirstname(firstname);
        customer.setLastname(lastname);
        customer.setEmail(email);
        customer.setDateborn(dateborn);
        customer.setPass(pass);
        customerService.save(customer);
        long id = customer.getId();

        URI createdUri = uriInf.getAbsolutePathBuilder().path(Long.toString(id)).build();
        return Response.created(createdUri).build();
    }

    @PUT
    @Path("/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response updateCustomers(@PathParam("id") Long id,

                                @FormParam("customerFn") String firstname,
                                    @FormParam("customerLn") String lastname,
                                    @FormParam("customerEmail") String email,
                                    @FormParam("customerDb") String dateborn,
                                    @FormParam("customerPass") String pass
                                   ) {
        CustomersEntity inDb = customerService.findOne(id);
        if (inDb == null){
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }
        else {
        inDb.setFirstname(firstname);
        inDb.setLastname(lastname);
        inDb.setEmail(email);
        inDb.setDateborn(dateborn);
        inDb.setPass(pass);
        customerService.update(inDb);
        }
        return Response.noContent().build();
    }

作为旁注,一种断言的测试方法并没有真正意义。

答案 1 :(得分:3)

尝试在infoPackage()方法

中移动以下语句

fh.setFormatter(formatter); logger.addHandler(fh);

因为方法调用会多次设置它们。

答案 2 :(得分:2)

每次添加邮件时都会添加相同的处理程序。你应该只做一次。我建议使用静态初始化器。

我已经注释掉了你不再需要的行:

public class MyExampleTest {
    //private FileHandler fh = null;
    private static final Logger logger;
    //SimpleFormatter formatter = new SimpleFormatter();

    static {
        logger = Logger.getLogger(MyExampleTest.class.getName());
        FileHandler fh = new FileHandler("test.log", true);
        fh.setFormatter(new SimpleFormatter());
        logger.addHandler(fh);
    }

    @Test
    public void infoPackage() throws Exception {
        //fh = new FileHandler("test.log", true);
        // do some test stuff
        writeEntryToLogFile("entry one");
        // do some more test stuff
        writeEntryToLogFile("entry two");
        // do even more test stuff
        writeEntryToLogFile("entry three");
    }

    private void writeEntryToLogFile(String message) throws Exception {
        //fh.setFormatter(formatter); 
        //logger.addHandler(fh);
        logger.info(message);
    }
}

值得注意的是writeEntryToLogFile现在有点无意义,因为它只是一条线。我已经摆脱了这个功能。

答案 3 :(得分:2)

问题在于您多次致电writeEntryToLogFile()并多次设置fileHandler

将调用方法中的2行移动为:

@Test
public void infoPackage() throws Exception {
    fh = new FileHandler("test.log", true);
    fh.setFormatter(formatter); 
    logger.addHandler(fh);
    // do some test stuff
    writeEntryToLogFile("entry one");
    // do some more test stuff
    writeEntryToLogFile("entry two");
    // do even more test stuff
    writeEntryToLogFile("entry three");
}

private void writeEntryToLogFile(String message) throws Exception {
    logger.info(message);
}

答案 4 :(得分:1)

只是详细说明Krishna Kuntala所说的内容,当你查看Logger类时,添加处理程序正在添加ArrayList

private final CopyOnWriteArrayList <Handler> handlers

由于您在第3次访问时第三次调用add处理程序,因此它将使用输出到同一文件的三个处理程序记录相同的语句。