@Test public void testChained() throws IOException { ChronicleTools.deleteOnExit(TMP + "/chronicle1"); Chronicle chronicle1 = new IndexedChronicle(TMP + "/chronicle1"); InProcessChronicleSource source1 = new InProcessChronicleSource(chronicle1, 61111); ChronicleTools.deleteOnExit(TMP + "/chronicle2"); Chronicle chronicle2 = new IndexedChronicle(TMP + "/chronicle2"); InProcessChronicleSource source2 = new InProcessChronicleSource(chronicle2, 62222); InProcessChronicleSink sink2 = new InProcessChronicleSink(source2, "localhost", 61111); ChronicleTools.deleteOnExit(TMP + "/chronicle3"); Chronicle chronicle3 = new IndexedChronicle(TMP + "/chronicle3"); InProcessChronicleSink sink3 = new InProcessChronicleSink(chronicle3, "localhost", 62222); ExcerptAppender excerpt1 = source1.createAppender(); ExcerptTailer excerpt2 = sink2.createTailer(); ExcerptTailer excerpt3 = sink3.createTailer(); for (int i = 1; i < 20; i++) { excerpt1.startExcerpt(); excerpt1.writeLong(System.nanoTime()); excerpt1.finish(); while (excerpt2.size() < i) excerpt2.nextIndex(); while (excerpt3.size() < i) excerpt3.nextIndex(); } sink3.close(); sink2.close(); source1.close(); }
protected synchronized String getIndexedTestPath() { final String path = TMP_DIR + "/ic-" + testName.getMethodName(); ChronicleTools.deleteOnExit(path); return path; }
@Test public void testChainedChronicleReconnection() throws IOException, InterruptedException { // create the 'source' chronicle ChronicleTools.deleteOnExit(TMP + "/chronicle1"); Chronicle chronicle = new IndexedChronicle(TMP + "/chronicle1"); InProcessChronicleSource chronicleSource = new InProcessChronicleSource(chronicle, 61111); // write some data into the 'source' chronicle ExcerptAppender sourceAppender = chronicleSource.createAppender(); long NUM_INITIAL_MESSAGES = 20; for (long i = 0; i < NUM_INITIAL_MESSAGES; i++) { sourceAppender.startExcerpt(); sourceAppender.writeLong(i); sourceAppender.flush(); sourceAppender.finish(); } // Starting first slave instance // create the 'slave' chronicle ChronicleTools.deleteOnExit(TMP + "/chronicle2"); Chronicle chronicle1 = new IndexedChronicle(TMP + "/chronicle2"); InProcessChronicleSource chronicleSource1 = new InProcessChronicleSource(chronicle1, 62222); InProcessChronicleSink chronicleSink1 = new InProcessChronicleSink(chronicleSource1, "localhost", 61111); // try to read current data from the 'slave' chronicle ExcerptTailer tailer1 = chronicleSink1.createTailer(); long nextIndex1 = 0; while (tailer1.nextIndex()) { assertEquals("Unexpected index in stream", tailer1.readLong(), nextIndex1++); } assertEquals("Unexpected number of messages in stream", NUM_INITIAL_MESSAGES, nextIndex1); // Close first 'slave' chronicle chronicleSink1.close(); chronicleSource1.close(); chronicle1.close(); // Write some more data for (long i = NUM_INITIAL_MESSAGES; i < NUM_INITIAL_MESSAGES * 2; i++) { sourceAppender.startExcerpt(); sourceAppender.writeLong(i); sourceAppender.flush(); sourceAppender.finish(); } // Starting second slave instance // Observe that we don't call ChronicleTools.deleteOnExit(file) - // the new instance will re-open the existing chronicle file Chronicle chronicle2 = new IndexedChronicle(TMP + "/chronicle2"); InProcessChronicleSource chronicleSource2 = new InProcessChronicleSource(chronicle2, 63333); InProcessChronicleSink chronicleSink2 = new InProcessChronicleSink(chronicleSource2, "localhost", 61111); ExcerptTailer tailer2 = chronicleSink2.createTailer(); long nextIndex2 = 0; while (tailer2.nextIndex()) { assertEquals("Unexpected message index in stream", tailer2.readLong(), nextIndex2++); } assertEquals("Didn't read all messages", NUM_INITIAL_MESSAGES * 2, nextIndex2); // Cleaning up chronicleSink2.close(); chronicleSource2.close(); chronicle2.close(); chronicleSource.close(); chronicle.close(); }
@SuppressWarnings("unchecked") public static void main(String... args) throws ParseException, JoranException, IOException { Parser parser = new BasicParser(); CommandLine cl = null; try { cl = parser.parse(OPTS, args); } catch (ParseException e) { HelpFormatter help = new HelpFormatter(); help.printHelp("dlog", OPTS, true); System.exit(-1); } LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); loggerContext.reset(); if (cl.hasOption("config")) { // Read Logback configuration JoranConfigurator configurator = new JoranConfigurator(); configurator.setContext(loggerContext); configurator.doConfigure(cl.getOptionValue("file", "logback.xml")); StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext); } else { BasicConfigurator.configure(loggerContext); } Appender appender = null; if (cl.hasOption("output")) { String outputAppender = cl.getOptionValue("output", "console"); appender = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).getAppender(outputAppender); } ChronicleTools.warmup(); Chronicle chronicle = new IndexedChronicle(cl.getOptionValue("path"), ChronicleConfig.DEFAULT); ExcerptTailer ex = chronicle.createTailer(); Level level = Level.valueOf(cl.getOptionValue("level", "TRACE")); if (cl.hasOption("head")) { int lines = Integer.parseInt(cl.getOptionValue("head", "10")); for (int i = 0; i < lines; i++) { LoggingEvent evt = readLoggingEvent(ex, loggerContext); if (evt.getLevel().isGreaterOrEqual(level)) { writeEvent(evt, appender); } } } else if (cl.hasOption("tail")) { int lines = Integer.parseInt(cl.getOptionValue("tail", "10")); Queue<LoggingEvent> tail = new LinkedBlockingQueue<LoggingEvent>(lines); while (ex.nextIndex()) { LoggingEvent evt = readLoggingEvent(ex, loggerContext); if (!tail.offer(evt)) { tail.poll(); tail.add(evt); } } LoggingEvent evt; while (null != (evt = tail.poll())) { if (evt.getLevel().isGreaterOrEqual(level)) { writeEvent(evt, appender); } } } else if (cl.hasOption("search")) { String regex = cl.getOptionValue("search"); Pattern regexPatt = Pattern.compile(regex); while (ex.nextIndex()) { LoggingEvent evt = readLoggingEvent(ex, loggerContext); if (null != evt && evt.getLevel().isGreaterOrEqual(level)) { if (regexPatt.matcher(evt.getFormattedMessage()).matches()) { writeEvent(evt, appender); } } } } loggerContext.stop(); chronicle.close(); }