/* * */ package org.smartly.commons.logging; import org.smartly.IConstants; import org.smartly.commons.util.FileUtils; import org.smartly.commons.util.PathUtils; import org.smartly.commons.util.StringUtils; import java.io.FileWriter; import java.io.IOException; import java.util.*; /** * This is an utility class for logging storage.<br/> * Properties:<br/> * <ul> * <li>FileEnabled: (Boolean - default=true) Enable/Disable writing on file (./logs/logging.log)</li><br/> * <li>MaxItems: (Integer - default=500) Max rows in list.</li><br/> * </ul> * * @author angelo.geminiani */ public final class LoggingRepository { // ------------------------------------------------------------------------ // Constants // ------------------------------------------------------------------------ private static final String DEFAULT = "default"; // ------------------------------------------------------------------------ // Variables // ------------------------------------------------------------------------ private Level _level = Level.INFO; private final Map<String, List<LogItem>> _data; private final Map<String, String> _customPaths; private String _root; private boolean _fileEnabled; private boolean _consoleEnabled; private int _maxItems; // ------------------------------------------------------------------------ // Constructor // ------------------------------------------------------------------------ public LoggingRepository() { _data = Collections.synchronizedMap(new HashMap<String, List<LogItem>>()); _customPaths = Collections.synchronizedMap(new HashMap<String, String>()); _fileEnabled = true; _consoleEnabled = true; _maxItems = 500; this.setFilePath(IConstants.PATH_LOG + "/logging.log"); } @Override public String toString() { synchronized (_data) { final StringBuilder result = new StringBuilder(); final List<LogItem> list = this.getLogItems(DEFAULT); for (final LogItem item : list) { if (result.length() > 0) { result.append(IConstants.LINE_SEPARATOR); } result.append(item.toString()); } return result.toString(); } } public String toString(final Logger logger) { final String key = this.getKey(logger); return this.toString(key); } public String toString(final String key) { synchronized (_data) { final StringBuilder result = new StringBuilder(); final List<LogItem> list = this.getLogItems(key); for (final LogItem item : list) { if (result.length() > 0) { result.append(IConstants.LINE_SEPARATOR); } result.append(item.toString()); } return result.toString(); } } // ------------------------------------------------------------------------ // public // ------------------------------------------------------------------------ /** * Set default file path * * @param path */ public void setFilePath(final String path) { _root = PathUtils.getParent(path); this.setLogFileName(DEFAULT, path); } /** * Set a custom log file. * * @param aclass Class of instance that logs in a separate file. * @param fileName File Name. i.e. "./memory.log" */ public void setLogFileName(final Class aclass, final String fileName) { final String key = this.getKey(aclass); this.setLogFileName(key, fileName); } /** * Set a custom log file. * * @param key Name of logger. Usually is name of calling class. * @param fileName File Name. i.e. "./memory.log" */ public void setLogFileName(final String key, final String fileName) { final String name = PathUtils.getFilename(fileName, true); final String absoluteFileName = PathUtils.join(_root, name); this.setAbsoluteLogFileName(key, absoluteFileName); } public void setAbsoluteLogFileName(final String key, final String absoluteFileName) { synchronized (_customPaths) { _customPaths.put(key, absoluteFileName); } synchronized (_data) { this.createLogItems(key); } } public String getAbsoluteLogFileName(final String name) { final String path = this.getCleanLogFileName(name); return PathUtils.getAbsolutePath(path); } public void setLevel(final Level level) { _level = level; } public Level getLevel() { return _level; } public boolean isFileEnabled() { return _fileEnabled; } public void setFileEnabled(boolean fileEnabled) { this._fileEnabled = fileEnabled; } public boolean isConsoleEnabled() { return _consoleEnabled; } public void setConsoleEnabled(boolean consoleEnabled) { this._consoleEnabled = consoleEnabled; } public int getMaxItems() { return _maxItems; } public void setMaxItems(int maxItems) { this._maxItems = maxItems; } public void clear() { synchronized (_data) { _data.clear(); } } public boolean isLoggable(final Level level) { return _level.getNumValue() <= level.getNumValue(); } public void log(final Logger logger, final Throwable t) { this.log(logger, Level.SEVERE, t, null); } public void log(final Logger logger, final String message) { this.log(logger, Level.INFO, null, message); } public void log(final Logger logger, final Level level, final String message) { this.log(logger, level, null, message); } public void log(final Logger logger, final Level level, final Throwable t) { this.log(logger, level, t, null); } public void log(final Logger logger, final Level level, final Throwable t, final String message) { synchronized (_data) { if (this.isLoggable(level)) { final String key = this.getKey(logger); final List<LogItem> logitems = this.getLogItems(logger.getName()); final LogItem item = new LogItem(logger.getName(), level, t, message); logitems.add(item); if (logitems.size() > _maxItems) { logitems.remove(logitems.size() - 1); } // this.invokeListeners(item); this.writeFile(logger); this.writeConsole(item); } } } // ------------------------------------------------------------------------ // p r i v a t e // ------------------------------------------------------------------------ private String getKey(final Class aclass) { if (null != aclass) { final Logger logger = new LogItemRepositoryLogger(aclass.getName(), ""); return this.getKey(logger); } return DEFAULT; } private String getKey(final Logger logger) { if (null != logger) { return logger.getName(); } return DEFAULT; } private String getRelativeLogFileName(final Class aclass) { final String key = this.getKey(aclass); return this.getCleanLogFileName(key); } private String getCleanLogFileName(final String name) { if (_customPaths.containsKey(name)) { final String path = _customPaths.get(name); return path; //path.startsWith(".")?path.substring(1):path; } return _customPaths.get(DEFAULT); } private List<LogItem> getLogItems(final String loggerName) { final String key = StringUtils.hasText(loggerName) ? loggerName : DEFAULT; if (_data.containsKey(key)) { return _data.get(key); } else { return _data.get(DEFAULT); } } private void createLogItems(final String key) { if (!_data.containsKey(key)) { final List<LogItem> result = new LinkedList<LogItem>(); _data.put(key, result); } } private List<LogItem> getAllLogItems() { final List<LogItem> result = new LinkedList<LogItem>(); final Collection<List<LogItem>> logs = _data.values(); for (final List<LogItem> list : logs) { for (final LogItem item : list) { result.add(item); } } return result; } private void writeFile(final Logger sender) { if (_fileEnabled) { final String fileName = this.getAbsoluteLogFileName(sender.getName()); final String text = this.toString(sender); try { FileUtils.mkdirs(fileName); FileUtils.copy(text, new FileWriter(fileName)); } catch (IOException ex) { System.out.println(ex); } } } private void writeConsole(final LogItem item) { if (_consoleEnabled) { System.out.println(item); } } // ------------------------------------------------------------------------ // S T A T I C // ------------------------------------------------------------------------ private static LoggingRepository __instance; public static LoggingRepository getInstance() { if (null == __instance) { __instance = new LoggingRepository(); } return __instance; } }