package com.tesora.dve.common.logutil;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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 this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import com.tesora.dve.common.PEConstants;
// responsible for collecting a set of individual executions
public class StructuredExecutionLogger implements ExecutionLogger {
protected long start = -1;
protected long end = -1;
protected LogSubject subject;
protected List<ExecutionLogger> subloggers = new ArrayList<ExecutionLogger>();
public StructuredExecutionLogger(LogSubject subj) {
subject = subj;
begin();
}
public List<ExecutionLogger> getSubLoggers() {
return subloggers;
}
public ExecutionLogger getCurrentSubLogger() {
if (subloggers.isEmpty())
return null;
return subloggers.get(subloggers.size() - 1);
}
public ExecutionLogger buildNewLogger(LogSubject subj) {
return new StructuredExecutionLogger(subj);
}
@Override
public ExecutionLogger getNewLogger(LogSubject subj) {
return addNewLogger(buildNewLogger(subj));
}
public ExecutionLogger addNewLogger(ExecutionLogger el) {
ExecutionLogger current = getCurrentSubLogger();
if (current == null || current.completed() || !(current instanceof StructuredExecutionLogger)) {
subloggers.add(el);
} else {
StructuredExecutionLogger sel = (StructuredExecutionLogger) current;
sel.addNewLogger(el);
}
return el;
}
@Override
public ExecutionLogger getNewLogger(String message) {
return addNewLogger(new StructuredExecutionLogger(new AdHocSubject(message)));
}
@Override
public void begin() {
start = System.nanoTime();
}
@Override
public void end() {
end = System.nanoTime();
}
@Override
public boolean completed() {
return start > -1 && end > -1;
}
@Override
public long getDelta() {
return end - start;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public LogSubject getSubject() {
return subject;
}
protected void accumulateLog(StringBuilder buf, String in) {
buf.append(in);
buf.append(PEConstants.LINE_SEPARATOR);
}
protected String getSelfLog(int level, String[] tags, StringBuilder buf, int offset, String indent) {
String t = (level < tags.length ? tags[level] : "unknown");
StringBuilder line = new StringBuilder();
line.append(indent);
if (level > 0)
// have to emit the offset
line.append("[").append(offset).append("] ");
line.append(t).append("=").append(getDelta()).append("; ").append(getSubject().describeForLog());
return line.toString();
}
protected void accumulateDescendantLog(int level, String[] tags, StringBuilder buf, String indent) {
int suboff = 0;
String subindent = indent + " ";
for(ExecutionLogger el : subloggers) {
if (el instanceof StructuredExecutionLogger) {
StructuredExecutionLogger sel = (StructuredExecutionLogger) el;
sel.accumulateLogMessage(level + 1, tags, buf, ++suboff, subindent);
}
}
}
protected void accumulateLogMessage(int level, String[] tags, StringBuilder buf, int offset, String indent) {
accumulateLog(buf,getSelfLog(level,tags,buf,offset,indent));
accumulateDescendantLog(level, tags, buf, indent);
}
}