| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.qpid.server.logging; |
| |
| import java.util.Iterator; |
| import org.apache.log4j.Appender; |
| import org.apache.log4j.Layout; |
| import org.apache.log4j.Logger; |
| import org.apache.log4j.spi.ErrorHandler; |
| import org.apache.log4j.spi.Filter; |
| import org.apache.log4j.spi.LoggingEvent; |
| |
| public class LogRecorder implements Appender, Iterable<LogRecorder.Record> |
| { |
| private ErrorHandler _errorHandler; |
| private Filter _filter; |
| private String _name; |
| private long _recordId; |
| |
| private final int _bufferSize = 4096; |
| private final int _mask = _bufferSize - 1; |
| private Record[] _records = new Record[_bufferSize]; |
| |
| |
| public static class Record |
| { |
| private final long _id; |
| private final String _logger; |
| private final long _timestamp; |
| private final String _threadName; |
| private final String _level; |
| private final String _message; |
| |
| |
| public Record(long id, LoggingEvent event) |
| { |
| _id = id; |
| _logger = event.getLoggerName(); |
| _timestamp = event.timeStamp; |
| _threadName = event.getThreadName(); |
| _level = event.getLevel().toString(); |
| _message = event.getRenderedMessage(); |
| } |
| |
| public long getId() |
| { |
| return _id; |
| } |
| |
| public long getTimestamp() |
| { |
| return _timestamp; |
| } |
| |
| public String getThreadName() |
| { |
| return _threadName; |
| } |
| |
| public String getLevel() |
| { |
| return _level; |
| } |
| |
| public String getMessage() |
| { |
| return _message; |
| } |
| |
| public String getLogger() |
| { |
| return _logger; |
| } |
| } |
| |
| public LogRecorder() |
| { |
| Logger.getRootLogger().addAppender(this); |
| } |
| |
| @Override |
| public void addFilter(Filter filter) |
| { |
| _filter = filter; |
| } |
| |
| @Override |
| public void clearFilters() |
| { |
| _filter = null; |
| } |
| |
| @Override |
| public void close() |
| { |
| } |
| |
| public void closeLogRecorder() |
| { |
| Logger.getRootLogger().removeAppender(this); |
| } |
| |
| @Override |
| public synchronized void doAppend(LoggingEvent loggingEvent) |
| { |
| _records[((int) (_recordId & _mask))] = new Record(_recordId, loggingEvent); |
| _recordId++; |
| } |
| |
| @Override |
| public ErrorHandler getErrorHandler() |
| { |
| return _errorHandler; |
| } |
| |
| @Override |
| public Filter getFilter() |
| { |
| return _filter; |
| } |
| |
| @Override |
| public Layout getLayout() |
| { |
| return null; |
| } |
| |
| @Override |
| public String getName() |
| { |
| return _name; |
| } |
| |
| @Override |
| public boolean requiresLayout() |
| { |
| return false; |
| } |
| |
| @Override |
| public void setErrorHandler(ErrorHandler errorHandler) |
| { |
| _errorHandler = errorHandler; |
| } |
| |
| @Override |
| public void setLayout(Layout layout) |
| { |
| |
| } |
| |
| @Override |
| public void setName(String name) |
| { |
| _name = name; |
| } |
| |
| @Override |
| public Iterator<Record> iterator() |
| { |
| return new RecordIterator(Math.max(_recordId-_bufferSize, 0l)); |
| } |
| |
| private class RecordIterator implements Iterator<Record> |
| { |
| private long _id; |
| |
| public RecordIterator(long currentRecordId) |
| { |
| _id = currentRecordId; |
| } |
| |
| @Override |
| public boolean hasNext() |
| { |
| return _id < _recordId; |
| } |
| |
| @Override |
| public Record next() |
| { |
| Record record = _records[((int) (_id & _mask))]; |
| while(_id < _recordId-_bufferSize) |
| { |
| _id = _recordId-_bufferSize; |
| record = _records[((int) (_id & _mask))]; |
| } |
| _id++; |
| return record; |
| } |
| |
| @Override |
| public void remove() |
| { |
| throw new UnsupportedOperationException(); |
| } |
| } |
| } |