/*
* 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.query.command;
import java.util.HashMap;
import java.util.Map;
import org.araqne.logdb.QueryCommand;
import org.araqne.logdb.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ParseKv extends QueryCommand {
private final Logger logger = LoggerFactory.getLogger(ParseKv.class);
private final String field;
private final boolean overlay;
private final String pairDelim;
private final String kvDelim;
public ParseKv(String field, boolean overlay, String pairDelim, String kvDelim) {
this.field = field;
this.overlay = overlay;
this.pairDelim = pairDelim;
this.kvDelim = kvDelim;
}
@Override
public String getName() {
return "parsekv";
}
public String getField() {
return field;
}
public boolean isOverlay() {
return overlay;
}
public String getPairDelim() {
return pairDelim;
}
public String getKvDelim() {
return kvDelim;
}
@Override
public void onPush(Row m) {
Object target = m.get(field);
if (target == null) {
if (overlay)
pushPipe(m);
return;
}
try {
String line = target.toString();
Map<String, Object> kv = new HashMap<String, Object>();
int lastPairFrom = 0;
while (true) {
int p = line.indexOf(pairDelim, lastPairFrom);
if (p < 0)
break;
String pairToken = line.substring(lastPairFrom, p).trim();
lastPairFrom = p + pairDelim.length();
if (pairToken.isEmpty())
continue;
int p2 = pairToken.indexOf(kvDelim);
if (p2 < 0) {
kv.put(pairToken, null);
} else {
String k = pairToken.substring(0, p2);
String v = pairToken.substring(p2 + kvDelim.length());
kv.put(k, v);
}
}
// add last pair
String pairToken = line.substring(lastPairFrom).trim();
if (!pairToken.isEmpty()) {
int p2 = pairToken.indexOf(kvDelim);
if (p2 < 0) {
kv.put(pairToken, null);
} else {
String k = pairToken.substring(0, p2);
String v = pairToken.substring(p2 + kvDelim.length());
kv.put(k, v);
}
}
Object table = m.get("_table");
Object time = m.get("_time");
if (m.get("_id") != null && !kv.containsKey("_id"))
kv.put("_id", m.get("_id"));
if (time != null && !kv.containsKey("_time"))
kv.put("_time", m.get("_time"));
if (table != null && !kv.containsKey("_table"))
kv.put("_table", m.get("_table"));
if (overlay) {
m.map().putAll(kv);
pushPipe(m);
} else {
pushPipe(new Row(kv));
}
} catch (Throwable t) {
// parsing fail handling
if (overlay)
pushPipe(m);
if (logger.isDebugEnabled())
logger.debug("araqne logdb: [" + toString() + "] failed, log data [{}]", m.map());
}
}
@Override
public String toString() {
String fieldOpt = "";
if (field != null && !field.equals("line"))
fieldOpt = " field=" + field;
String overlayOpt = "";
if (overlay)
overlayOpt = " overlay=t";
String pairDelimOpt = "";
if (!pairDelim.equals(" "))
pairDelimOpt = " pairdelim=\"" + pairDelim + "\"";
String kvDelimOpt = "";
if (!kvDelim.equals("="))
kvDelimOpt = " kvdelim=\"" + kvDelim + "\"";
return "parsekv" + fieldOpt + overlayOpt + pairDelimOpt + kvDelimOpt;
}
}