Skip to content

Commit

Permalink
Merge branch 'master' into update-forms
Browse files Browse the repository at this point in the history
  • Loading branch information
janfaracik committed Nov 28, 2021
2 parents 9281ae8 + d2fa876 commit 0b1d8ed
Show file tree
Hide file tree
Showing 35 changed files with 765 additions and 163 deletions.
161 changes: 125 additions & 36 deletions core/src/main/java/hudson/logging/LogRecorder.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*
* The MIT License
*
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -28,8 +28,14 @@
import hudson.BulkChange;
import hudson.Extension;
import hudson.FilePath;
import hudson.RestrictedSince;
import hudson.Util;
import hudson.XmlFile;
import hudson.util.CopyOnWriteList;
import hudson.util.HttpResponses;
import java.util.Objects;
import jenkins.util.MemoryReductionUtil;
import jenkins.model.Jenkins;
import hudson.model.AbstractModelObject;
import hudson.model.AutoCompletionCandidates;
import hudson.model.Computer;
Expand All @@ -39,8 +45,6 @@
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
import hudson.slaves.ComputerListener;
import hudson.util.CopyOnWriteList;
import hudson.util.HttpResponses;
import hudson.util.RingBufferLogHandler;
import hudson.util.XStream2;
import java.io.File;
Expand All @@ -66,9 +70,7 @@
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import jenkins.model.Jenkins;
import jenkins.security.MasterToSlaveCallable;
import jenkins.util.MemoryReductionUtil;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.accmod.Restricted;
Expand Down Expand Up @@ -97,13 +99,54 @@
public class LogRecorder extends AbstractModelObject implements Saveable {
private volatile String name;

public final CopyOnWriteList<Target> targets = new CopyOnWriteList<>();
@Deprecated
@Restricted(NoExternalUse.class)
@RestrictedSince("TODO")
/**
* No longer used.
*
* @deprecated use {@link #getLoggers()}
*/
public final transient CopyOnWriteList<Target> targets = new CopyOnWriteList<>();
private List<Target> loggers = new ArrayList<>();
private static final TargetComparator TARGET_COMPARATOR = new TargetComparator();


@DataBoundConstructor
public LogRecorder(String name) {
this.name = name;
// register it only once when constructed, and when this object dies
// WeakLogHandler will remove it
new WeakLogHandler(handler,Logger.getLogger(""));
}

private Object readResolve() {
if (loggers == null) {
loggers = new ArrayList<>();
}

List<Target> tempLoggers = new ArrayList<>(loggers);

if (!targets.isEmpty()) {
loggers.addAll(targets.getView());
}
if (!tempLoggers.isEmpty() && !targets.getView().equals(tempLoggers)) {
targets.addAll(tempLoggers);
}
return this;
}

public List<Target> getLoggers() {
return loggers;
}

public void setLoggers(List<Target> loggers) {
this.loggers = loggers;
}

@Restricted(NoExternalUse.class)
Target[] orderedTargets() {
// will contain targets ordered by reverse name length (place specific targets at the beginning)
Target[] ts = targets.toArray(new Target[]{});
Target[] ts = loggers.toArray(new Target[]{});

Arrays.sort(ts, TARGET_COMPARATOR);

Expand Down Expand Up @@ -220,6 +263,23 @@ public String getName() {
return name;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Target target = (Target) o;
return level == target.level && Objects.equals(name, target.name);
}

@Override
public int hashCode() {
return Objects.hash(name, level);
}

@Deprecated
public boolean includes(LogRecord r) {
if(r.getLevel().intValue() < level)
Expand Down Expand Up @@ -272,7 +332,7 @@ public void disable() {
}

}

private static class TargetComparator implements Comparator<Target>, Serializable {

private static final long serialVersionUID = 9285340752515798L;
Expand Down Expand Up @@ -316,21 +376,14 @@ void broadcast() {

@Extension @Restricted(NoExternalUse.class) public static final class ComputerLogInitializer extends ComputerListener {
@Override public void preOnline(Computer c, Channel channel, FilePath root, TaskListener listener) throws IOException, InterruptedException {
for (LogRecorder recorder : Jenkins.get().getLog().logRecorders.values()) {
for (Target t : recorder.targets) {
for (LogRecorder recorder : Jenkins.get().getLog().getRecorders()) {
for (Target t : recorder.getLoggers()) {
channel.call(new SetLevel(t.name, t.getLevel()));
}
}
}
}

public LogRecorder(String name) {
this.name = name;
// register it only once when constructed, and when this object dies
// WeakLogHandler will remove it
new WeakLogHandler(handler,Logger.getLogger(""));
}

@Override
public String getDisplayName() {
return name;
Expand Down Expand Up @@ -364,16 +417,16 @@ public synchronized void doConfigSubmit( StaplerRequest req, StaplerResponse rsp
Jenkins.checkGoodName(newName);
oldFile = getConfigFile();
// rename
getParent().logRecorders.remove(name);
List<LogRecorder> recorders = getParent().getRecorders();
recorders.remove(new LogRecorder(name));
this.name = newName;
getParent().logRecorders.put(name,this);
recorders.add(this);
getParent().setRecorders(recorders); // ensure that legacy logRecorders field is synced on save
redirect = "../" + Util.rawEncode(newName) + '/';
}

List<Target> newTargets = req.bindJSONToList(Target.class, src.get("targets"));
for (Target t : newTargets)
t.enable();
targets.replaceBy(newTargets);
List<Target> newTargets = req.bindJSONToList(Target.class, src.get("loggers"));
setLoggers(newTargets);

save();
if (oldFile!=null) oldFile.delete();
Expand All @@ -393,8 +446,7 @@ public HttpResponse doClear() throws IOException {
*/
public synchronized void load() throws IOException {
getConfigFile().unmarshal(this);
for (Target t : targets)
t.enable();
loggers.forEach(Target::enable);
}

/**
Expand All @@ -403,10 +455,49 @@ public synchronized void load() throws IOException {
@Override
public synchronized void save() throws IOException {
if(BulkChange.contains(this)) return;

handlePluginUpdatingLegacyLogManagerMap();
getConfigFile().write(this);
loggers.forEach(Target::enable);

SaveableListener.fireOnChange(this, getConfigFile());
}

@SuppressWarnings("deprecation") // this is for compatibility
private void handlePluginUpdatingLegacyLogManagerMap() {
if (getParent().logRecorders.size() > getParent().getRecorders().size()) {
for (LogRecorder logRecorder : getParent().logRecorders.values()) {
if (!getParent().getRecorders().contains(logRecorder)) {
getParent().getRecorders().add(logRecorder);
}
}
}
if (getParent().getRecorders().size() > getParent().logRecorders.size()) {
for (LogRecorder logRecorder : getParent().getRecorders()) {
if (!getParent().logRecorders.containsKey(logRecorder.getName())) {
getParent().logRecorders.put(logRecorder.getName(), logRecorder);
}
}
}
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LogRecorder that = (LogRecorder) o;
return name.equals(that.name);
}

@Override
public int hashCode() {
return Objects.hash(name);
}

/**
* Deletes this recorder, then go back to the parent.
*/
Expand All @@ -415,14 +506,12 @@ public synchronized void doDoDelete(StaplerResponse rsp) throws IOException, Ser
Jenkins.get().checkPermission(Jenkins.ADMINISTER);

getConfigFile().delete();
getParent().logRecorders.remove(name);
getParent().getRecorders().remove(new LogRecorder(name));
// Disable logging for all our targets,
// then reenable all other loggers in case any also log the same targets
for (Target t : targets)
t.disable();
for (LogRecorder log : getParent().logRecorders.values())
for (Target t : log.targets)
t.enable();
loggers.forEach(Target::disable);

getParent().getRecorders().forEach(logRecorder -> logRecorder.getLoggers().forEach(Target::enable));
rsp.sendRedirect2("..");
}

Expand Down Expand Up @@ -468,7 +557,7 @@ public int compare(Computer c1, Computer c2) {
List<LogRecord> recs = new ArrayList<>();
try {
for (LogRecord rec : c.getLogRecords()) {
for (Target t : targets) {
for (Target t : loggers) {
if (t.includes(rec)) {
recs.add(rec);
break;
Expand Down
Loading

0 comments on commit 0b1d8ed

Please sign in to comment.