/* * Copyright 2013 Eediom Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.araqne.logdb.impl; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.araqne.api.Script; import org.araqne.api.ScriptArgument; import org.araqne.api.ScriptContext; import org.araqne.api.ScriptUsage; import org.araqne.logstorage.Log; import org.araqne.logstorage.LogBatchPacker; import org.araqne.logstorage.LogCallback; import org.araqne.logstorage.LogStorage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import au.com.bytecode.opencsv.CSVReader; public class CsvImportScript implements Script { private final Logger logger = LoggerFactory.getLogger(CsvImportScript.class); private final LogStorage storage; private ScriptContext context; public CsvImportScript(LogStorage storage) { this.storage = storage; } @Override public void setScriptContext(ScriptContext context) { this.context = context; } @ScriptUsage(description = "import text log file", arguments = { @ScriptArgument(name = "table name", type = "string", description = "table name"), @ScriptArgument(name = "file path", type = "string", description = "text log file path"), @ScriptArgument(name = "parse date", type = "string", description = "true or false", optional = true), @ScriptArgument(name = "charset", type = "string", description = "utf8 by default", optional = true), }) public void importCsvFile(String[] args) throws InterruptedException { String table = args[0]; String path = args[1]; String charset = "utf-8"; String[] dateColumns = null; SimpleDateFormat dateFormat = null; if (args.length > 2 && Boolean.parseBoolean(args[2])) { context.print("date columns? "); String cols = context.readLine(); dateColumns = cols.split(","); for (int i = 0; i < dateColumns.length; i++) dateColumns[i] = dateColumns[i].trim(); context.print("date format? "); String format = context.readLine().trim(); context.print("date locale? "); String locale = context.readLine().trim(); if (locale.isEmpty()) locale = "en"; dateFormat = new SimpleDateFormat(format, new Locale(locale)); } if (args.length > 3) charset = args[3]; long begin = System.currentTimeMillis(); FileInputStream fis = null; InputStreamReader isr = null; CSVReader reader = null; String[] headers = null; LogBatchPacker packer = null; long count = 0; try { fis = new FileInputStream(path); isr = new InputStreamReader(fis, charset); reader = new CSVReader(isr, ',', '\"', '\0'); packer = new LogBatchPacker(table, 2000, 100, new LogCallback() { @Override public void onLogBatch(String tableName, List<Log> logBatch) { try { storage.write(logBatch); } catch (InterruptedException e) { } } }); while (true) { String[] line = reader.readNext(); if (line == null) break; if (headers == null) { headers = line; continue; } Map<String, Object> data = new HashMap<String, Object>(); for (int i = 0; i < line.length; i++) { data.put(headers[i], line[i]); } Date date = parseDate(data, dateColumns, dateFormat); Log log = new Log(table, date, data); packer.pack(log); count++; } long end = System.currentTimeMillis(); long elapsed = end - begin; long speed = count * 1000 / elapsed; packer.flush(); context.println("loaded " + count + " logs in " + elapsed + "ms, " + speed + "logs/sec"); } catch (IOException e) { context.println("failed to load csv - " + e.getMessage()); logger.error("araqne logdb: cannot load csv file", e); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { } } if (isr != null) { try { isr.close(); } catch (IOException e) { } } if (fis != null) { try { fis.close(); } catch (IOException e) { } } packer.close(); } } private Date parseDate(Map<String, Object> data, String[] dateColumns, SimpleDateFormat df) { if (dateColumns == null || df == null) return new Date(); String s = ""; for (String c : dateColumns) { Object v = data.get(c); if (v != null) s += v; } Date d = df.parse(s, new ParsePosition(0)); if (d == null) return new Date(); return d; } }