blob: 8547060289f56bb6d13c021256e5ad4c9ca980a1 [file] [log] [blame]
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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 com.intellij.idea;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.SLRUMap;
import org.apache.log4j.Level;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedList;
import java.util.List;
public class RareLogger extends Logger {
// key to last log time for key
private final SLRUMap<Object, Long> myCache;
private final List<LogFilter> myConvertors;
private final LogFilter myProxy;
private final Logger myLogger;
private RareLogger(final Logger logger, final boolean fairSynch) {
myLogger = logger;
final Object lock = new Object();
myCache = new SLRUMap<Object, Long>(64, 32) {
@Override
public Long get(Object key) {
if (fairSynch) {
synchronized (lock) {
return super.get(key);
}
}
return super.get(key);
}
@Override
public void put(Object key, @NotNull Long value) {
if (fairSynch) {
synchronized (lock) {
super.put(key, value);
return;
}
}
super.put(key, value);
}
@Override
public boolean remove(Object key) {
if (fairSynch) {
synchronized (lock) {
return super.remove(key);
}
}
return super.remove(key);
}
};
myConvertors = new LinkedList<LogFilter>();
// just passes to parent logger
myProxy = new LogFilter() {
@Override
@NotNull
public Integer getAllowedLoggingInterval(Level level, String message, Throwable t, String[] details) {
return -1;
}
@Override
public Object getKey(@NotNull Level level,
@NonNls String message,
@Nullable Throwable t,
@NonNls String... details) {
if (Level.DEBUG.equals(level)) {
logger.debug(message, t);
} else if (Level.INFO.equals(level)) {
logger.info(message, t);
} else if (Level.WARN.equals(level)) {
logger.warn(message, t);
} else if (Level.ERROR.equals(level)) {
logger.error(message, t, details);
}
return null;
}
};
}
public void addFilter(final LogFilter logFilter) {
myConvertors.add(logFilter);
}
public static Logger wrap(final Logger logger, final boolean fairSynch) {
return new RareLogger(logger, fairSynch);
}
public static Logger wrap(final Logger logger, final boolean fairSynch, final LogFilter... filters) {
final RareLogger rareLogger = new RareLogger(logger, fairSynch);
for (LogFilter filter : filters) {
rareLogger.addFilter(filter);
}
return rareLogger;
}
@Override
public void debug(@NonNls String message) {
process(Level.DEBUG, message, null);
}
@Override
public boolean isDebugEnabled() {
return myLogger.isDebugEnabled();
}
@Override
public void debug(Throwable t) {
process(Level.DEBUG, null, t);
}
@Override
public void debug(@NonNls String message, Throwable t) {
process(Level.DEBUG, message, t);
}
@Override
public void error(@NonNls String message, @Nullable Throwable t, @NotNull @NonNls String... details) {
process(Level.ERROR, message, t, details);
}
@Override
public void info(@NonNls String message) {
process(Level.INFO, message, null);
}
@Override
public void info(@NonNls String message, Throwable t) {
process(Level.INFO, message, t);
}
@Override
public void warn(@NonNls String message, Throwable t) {
process(Level.WARN, message, t);
}
@Override
public void setLevel(Level level) {
myLogger.setLevel(level);
}
private void process(@NotNull final Level level, @NonNls @Nullable final String message, @Nullable final Throwable t, @NonNls final String... details) {
if (! Level.ERROR.equals(level)) {
for (LogFilter convertor : myConvertors) {
final Object key = convertor.getKey(level, message, t, details);
if (key != null) {
final Long latestMoment = myCache.get(key);
if (latestMoment != null && ((System.currentTimeMillis() - latestMoment) < convertor.getAllowedLoggingInterval(level, message, t, details))) {
return;
} else {
// log and put to cache
myCache.put(key, System.currentTimeMillis());
break;
}
}
}
}
// pass
myProxy.getKey(level, message, t, details);
}
public interface LogFilter {
@Nullable
Object getKey(@NotNull final Level level, @NonNls final String message, @Nullable final Throwable t, @NonNls final String... details);
@NotNull
Integer getAllowedLoggingInterval(Level level, String message, Throwable t, String[] details);
}
}