Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1452 from Graylog2/logs-rest
Make internal logs accessible via REST API call (cherry picked from commit 866d6e3)
- Loading branch information
1 parent
fa7d149
commit 23e94ec
Showing
7 changed files
with
352 additions
and
9 deletions.
There are no files selected for viewing
62 changes: 62 additions & 0 deletions
62
...s/src/main/java/org/graylog2/rest/models/system/loggers/responses/InternalLogMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package org.graylog2.rest.models.system.loggers.responses; | ||
|
||
|
||
import com.fasterxml.jackson.annotation.JsonAutoDetect; | ||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.google.auto.value.AutoValue; | ||
import org.hibernate.validator.constraints.NotEmpty; | ||
import org.joda.time.DateTime; | ||
|
||
import javax.annotation.Nullable; | ||
import javax.validation.constraints.NotNull; | ||
import java.util.Map; | ||
|
||
@AutoValue | ||
@JsonAutoDetect | ||
public abstract class InternalLogMessage { | ||
@JsonProperty | ||
@NotEmpty | ||
public abstract String message(); | ||
|
||
@JsonProperty("class_name") | ||
@NotEmpty | ||
public abstract String className(); | ||
|
||
@JsonProperty | ||
@NotEmpty | ||
public abstract String level(); | ||
|
||
@JsonProperty | ||
@Nullable | ||
public abstract String marker(); | ||
|
||
@JsonProperty | ||
@NotNull | ||
public abstract DateTime timestamp(); | ||
|
||
@JsonProperty | ||
@Nullable | ||
public abstract String throwable(); | ||
|
||
@JsonProperty("thread_name") | ||
@NotEmpty | ||
public abstract String threadName(); | ||
|
||
@JsonProperty | ||
@NotNull | ||
public abstract Map<String, String> context(); | ||
|
||
@JsonCreator | ||
public static InternalLogMessage create(@JsonProperty("message") @NotEmpty String message, | ||
@JsonProperty("class_name") @NotEmpty String className, | ||
@JsonProperty("level") @NotEmpty String level, | ||
@JsonProperty("marker") @Nullable String marker, | ||
@JsonProperty("timestamp") @NotNull DateTime timestamp, | ||
@JsonProperty("throwable") @Nullable String throwable, | ||
@JsonProperty("thread_name") @NotEmpty String threadName, | ||
@JsonProperty("context") @NotNull Map<String, String> context) { | ||
return new AutoValue_InternalLogMessage(message, className, level, marker, timestamp, throwable, threadName, context); | ||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
...s/src/main/java/org/graylog2/rest/models/system/loggers/responses/LogMessagesSummary.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* This file is part of Graylog. | ||
* | ||
* Graylog is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* Graylog is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with Graylog. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package org.graylog2.rest.models.system.loggers.responses; | ||
|
||
import com.fasterxml.jackson.annotation.JsonAutoDetect; | ||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.google.auto.value.AutoValue; | ||
|
||
import java.util.Collection; | ||
|
||
@AutoValue | ||
@JsonAutoDetect | ||
public abstract class LogMessagesSummary { | ||
|
||
@JsonProperty | ||
public abstract Collection<InternalLogMessage> messages(); | ||
|
||
@JsonCreator | ||
public static LogMessagesSummary create(@JsonProperty("messages") Collection<InternalLogMessage> messages) { | ||
return new AutoValue_LogMessagesSummary(messages); | ||
} | ||
|
||
} |
102 changes: 102 additions & 0 deletions
102
graylog2-server/src/main/java/org/graylog2/log4j/MemoryAppender.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/** | ||
* This file is part of Graylog. | ||
* | ||
* Graylog is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* Graylog is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with Graylog. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package org.graylog2.log4j; | ||
|
||
import org.apache.commons.collections.buffer.CircularFifoBuffer; | ||
import org.apache.logging.log4j.core.Filter; | ||
import org.apache.logging.log4j.core.Layout; | ||
import org.apache.logging.log4j.core.LogEvent; | ||
import org.apache.logging.log4j.core.appender.AbstractAppender; | ||
import org.apache.logging.log4j.core.config.plugins.Plugin; | ||
import org.apache.logging.log4j.core.config.plugins.PluginAttribute; | ||
import org.apache.logging.log4j.core.config.plugins.PluginElement; | ||
import org.apache.logging.log4j.core.config.plugins.PluginFactory; | ||
import org.apache.logging.log4j.core.layout.PatternLayout; | ||
import org.apache.logging.log4j.core.util.Booleans; | ||
|
||
import java.io.Serializable; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* A Log4J appender that keeps a configurable number of messages in memory. Used to make recent internal log messages | ||
* available via the REST API. | ||
*/ | ||
@Plugin(name = "Memory", category = "Core", elementType = "appender", printObject = true) | ||
public class MemoryAppender extends AbstractAppender { | ||
|
||
private CircularFifoBuffer buffer; | ||
private int bufferSize; | ||
|
||
protected MemoryAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions, int bufferSize) { | ||
super(name, filter, layout, ignoreExceptions); | ||
this.bufferSize = bufferSize; | ||
this.buffer = new CircularFifoBuffer(bufferSize); | ||
} | ||
|
||
@PluginFactory | ||
public static MemoryAppender createAppender( | ||
@PluginElement("Layout") Layout<? extends Serializable> layout, | ||
@PluginElement("Filter") final Filter filter, | ||
@PluginAttribute("name") final String name, | ||
@PluginAttribute(value = "bufferSize", defaultInt = 500) final String bufferSize, | ||
@PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final String ignore) { | ||
if (name == null) { | ||
LOGGER.error("No name provided for MemoryAppender"); | ||
return null; | ||
} | ||
|
||
if (layout == null) { | ||
layout = PatternLayout.createDefaultLayout(); | ||
} | ||
|
||
final int size = Integer.parseInt(bufferSize); | ||
final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); | ||
return new MemoryAppender(name, filter, layout, ignoreExceptions, size); | ||
} | ||
|
||
|
||
@Override | ||
public void append(LogEvent event) { | ||
buffer.add(event); | ||
} | ||
|
||
@Override | ||
public void stop() { | ||
super.stop(); | ||
buffer.clear(); | ||
} | ||
|
||
public List<LogEvent> getLogMessages(int max) { | ||
if (buffer == null) { | ||
throw new IllegalStateException("Cannot return log messages: Appender is not initialized."); | ||
} | ||
|
||
final List<LogEvent> result = new ArrayList<>(max); | ||
final Object[] messages = buffer.toArray(); | ||
for (int i = messages.length - 1; i >= 0 && i >= messages.length - max; i--) { | ||
result.add((LogEvent) messages[i]); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
public int getBufferSize() { | ||
return bufferSize; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.