/*******************************************************************************
*
* Copyright (c) 2004-2010 Oracle Corporation.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*
* Kohsuke Kawaguchi
*
*
*******************************************************************************/
package hudson.logging;
import hudson.FeedAdapter;
import hudson.Functions;
import hudson.init.Initializer;
import static hudson.init.InitMilestone.PLUGINS_PREPARED;
import hudson.model.AbstractModelObject;
import hudson.model.Hudson;
import hudson.model.RSS;
import hudson.tasks.Mailer;
import hudson.util.CopyOnWriteMap;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpRedirect;
import javax.servlet.ServletException;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
* Owner of {@link LogRecorder}s, bound to "/log".
*
* @author Kohsuke Kawaguchi
*/
public class LogRecorderManager extends AbstractModelObject {
/**
* {@link LogRecorder}s.
*/
public transient final Map<String, LogRecorder> logRecorders = new CopyOnWriteMap.Tree<String, LogRecorder>();
public String getDisplayName() {
return Messages.LogRecorderManager_DisplayName();
}
public String getSearchUrl() {
return "/log";
}
public LogRecorder getDynamic(String token) {
return getLogRecorder(token);
}
public LogRecorder getLogRecorder(String token) {
return logRecorders.get(token);
}
/**
* Loads the configuration from disk.
*/
public void load() throws IOException {
logRecorders.clear();
File dir = new File(Hudson.getInstance().getRootDir(), "log");
File[] files = dir.listFiles((FileFilter) new WildcardFileFilter("*.xml"));
if (files == null) {
return;
}
for (File child : files) {
String name = child.getName();
name = name.substring(0, name.length() - 4); // cut off ".xml"
LogRecorder lr = new LogRecorder(name);
lr.load();
logRecorders.put(name, lr);
}
}
/**
* Creates a new log recorder.
*/
public HttpResponse doNewLogRecorder(@QueryParameter String name) {
Hudson.checkGoodName(name);
logRecorders.put(name, new LogRecorder(name));
// redirect to the config screen
return new HttpRedirect(name + "/configure");
}
/**
* Configure the logging level.
*/
public HttpResponse doConfigLogger(@QueryParameter String name, @QueryParameter String level) {
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
Level lv;
if (level.equals("inherit")) {
lv = null;
} else {
lv = Level.parse(level.toUpperCase(Locale.ENGLISH));
}
Logger.getLogger(name).setLevel(lv);
return new HttpRedirect("levels");
}
/**
* RSS feed for log entries.
*/
public void doRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
doRss(req, rsp, getDisplayName(), Hudson.logRecords);
}
/**
* Renders the given log recorders as RSS.
*/
/*package*/ static void doRss(StaplerRequest req, StaplerResponse rsp, String recorderName, List<LogRecord> logs) throws IOException, ServletException {
// filter log records based on the log level
String level = req.getParameter("level");
if (level != null) {
Level threshold = Level.parse(level);
List<LogRecord> filtered = new ArrayList<LogRecord>();
for (LogRecord r : logs) {
if (r.getLevel().intValue() >= threshold.intValue()) {
filtered.add(r);
}
}
logs = filtered;
}
RSS.forwardToRss("Hudson " + recorderName + " log", "", logs, new FeedAdapter<LogRecord>() {
public String getEntryTitle(LogRecord entry) {
return entry.getMessage();
}
public String getEntryUrl(LogRecord entry) {
return "log"; // TODO: one URL for one log entry?
}
public String getEntryID(LogRecord entry) {
return String.valueOf(entry.getSequenceNumber());
}
public String getEntryDescription(LogRecord entry) {
return Functions.printLogRecord(entry);
}
public Calendar getEntryTimestamp(LogRecord entry) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeInMillis(entry.getMillis());
return cal;
}
public String getEntryAuthor(LogRecord entry) {
return Mailer.descriptor().getAdminAddress();
}
}, req, rsp);
}
@Initializer(before = PLUGINS_PREPARED)
public static void init(Hudson h) throws IOException {
h.getLog().load();
}
}