/**
* Copyright 2012-2014 Rafal Lewczuk <rafal.lewczuk@jitlogic.com>
* <p/>
* This is free software. You can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
* <p/>
* This software 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 General Public License for more details.
* <p/>
* You should have received a copy of the GNU General Public License
* along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jitlogic.zorka.common.zico;
import com.jitlogic.zorka.common.tracedata.FressianTraceFormat;
import com.jitlogic.zorka.common.tracedata.TraceRecord;
import org.fressian.FressianReader;
import org.fressian.FressianWriter;
import java.io.*;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
/**
* This class can be used to bulk load trace files generated by agent to remote collector.
* This is more often than not used for test purposes.
*
* @author rafal.lewczuk@jitlogic.com
*/
public class ZicoDataLoader {
/**
* Connection to ZICO server
*/
private ZicoClientConnector conn;
/**
* Maximum (uncompressed) packet size.
*/
private int packetSize = 8 * 1048576;
private int records = 0;
private long bytes = 0;
/**
* Creates new loader object
*
* @param addr hostname or IP address of ZICO collector server
* @param port collector port number
* @param hostname hostname advertised to collector server (data will be submitted as this name);
* @param auth client passphrase (if collector is working in secure mode)
* @throws IOException if connection breaks or collector login fails;
*/
public ZicoDataLoader(String addr, int port, String hostname, String auth) throws IOException {
conn = new ZicoClientConnector(addr, port);
conn.connect();
conn.hello(hostname, auth);
}
/**
* Opens trace file. Returns input stream object that will skip headers and stream trace file contents,
* uncompressing it on the fly if necessary.
*
* @param file file to be opened
* @return input stream reading file content
* @throws IOException if file does not exist, is malformed or I/O error occurs;
*/
public static InputStream open(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
byte[] hdr = new byte[4];
fis.read(hdr);
if (hdr[0] != 'Z' || hdr[1] != 'T' || hdr[2] != 'R') {
throw new IOException("Invalid header (invalid file type).");
}
if (hdr[3] == 'Z') {
InputStream is = new BufferedInputStream(new InflaterInputStream(fis, new Inflater(true), 65536));
return is;
} else if (hdr[3] == 'C') {
return new BufferedInputStream(fis);
} else {
throw new IOException("Invalid header (invalid file type).");
}
}
/**
* Opens trace file at specified location and submits its content to collector server.
*
* @param path path to .trc file
*/
public void load(String path) {
InputStream is = null;
try {
is = open(new File(path));
load(is);
} catch (EOFException e) {
} catch (IOException e) {
e.printStackTrace();
try {
if (is != null) {
is.close();
}
} catch (IOException e1) {
}
}
}
/**
* Parses trace data and submits it to remote collector.
*
* @param is input stream representing trace file content.
* @throws IOException if connection breaks or server-side data processing error occurs;
*/
public void load(InputStream is) throws IOException {
FressianReader reader = new FressianReader(is, FressianTraceFormat.READ_LOOKUP);
ByteArrayOutputStream os = new ByteArrayOutputStream();
FressianWriter writer = new FressianWriter(os, FressianTraceFormat.WRITE_LOOKUP);
Object obj;
while (null != (obj = reader.readObject())) {
writer.writeObject(obj);
if (obj instanceof TraceRecord) {
records++;
}
if (obj instanceof TraceRecord && os.size() > packetSize) {
conn.send(ZicoPacket.ZICO_DATA, os.toByteArray());
ZicoPacket rslt = conn.recv();
if (rslt.getStatus() != ZicoPacket.ZICO_OK) {
throw new ZicoException(rslt.getStatus(), "Error submitting data.");
}
bytes += os.size();
os = new ByteArrayOutputStream();
writer = new FressianWriter(os, FressianTraceFormat.WRITE_LOOKUP);
//System.out.print(".");
}
}
}
public int getRecords() {
return records;
}
public long getBytes() {
return bytes;
}
}