/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with VoltDB. If not, see <http://www.gnu.org/licenses/>. */ package org.voltdb.utils; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Queue; import java.util.zip.GZIPOutputStream; import org.codehaus.jackson.map.ObjectMapper; import org.voltcore.logging.VoltLogger; /** * Reads trace events from VoltTrace queue and writes them to files. */ public class TraceFileWriter implements Runnable { private static final VoltLogger s_logger = new VoltLogger("TRACER"); private final File m_path; private final Queue<VoltTrace.TraceEventBatch> m_events; public TraceFileWriter(File path, Queue<VoltTrace.TraceEventBatch> events) { m_events = events; m_path = path; } @Override public void run() { final ObjectMapper jsonMapper = new ObjectMapper(); BufferedWriter fileWriter = null; long firstEventTime = 0; long count = 0; try { VoltTrace.TraceEventBatch eventSupplier; while ((eventSupplier = m_events.poll()) != null) { VoltTrace.TraceEvent event; while ((event = eventSupplier.nextEvent()) != null) { if (fileWriter == null) { fileWriter = startTraceFile(m_path); firstEventTime = event.getNanos(); } else { fileWriter.write(","); } event.setSyncNanos(firstEventTime); String json = jsonMapper.writeValueAsString(event); fileWriter.newLine(); fileWriter.write(json); fileWriter.flush(); count++; } } } catch(IOException e) { // also catches JSON exceptions s_logger.info("Unexpected IO exception in trace file writer. Stopping trace file writer.", e); } if (fileWriter != null) { close(fileWriter); } s_logger.info("Wrote " + count + " trace events to " + m_path.getAbsolutePath()); } private static void close(BufferedWriter bw) { try { bw.newLine(); bw.write("]"); bw.newLine(); bw.flush(); bw.close(); } catch(IOException e) { if (s_logger.isDebugEnabled()) { s_logger.debug("Exception closing trace file buffered writer", e); } } } private static BufferedWriter startTraceFile(File path) throws IOException { // Uses the default platform encoding for now. final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(new FileOutputStream(path)))); bw.write("["); bw.flush(); return bw; } }