You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2017/10/18 12:01:52 UTC
[1/2] karaf git commit: [KARAF-5354] The log:get and log:set commands
should support etc/log4j2.xml configuration
Repository: karaf
Updated Branches:
refs/heads/master 48f26e60d -> b52309a36
[KARAF-5354] The log:get and log:set commands should support etc/log4j2.xml configuration
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b52309a3
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b52309a3
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b52309a3
Branch: refs/heads/master
Commit: b52309a363c46de844e047d391a8d392ea1ee3f9
Parents: 965ac92
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Oct 18 13:59:05 2017 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Oct 18 14:01:21 2017 +0200
----------------------------------------------------------------------
.../karaf/log/core/internal/LogServiceImpl.java | 8 +
.../core/internal/LogServiceLog4j2XmlImpl.java | 265 +++++++++++++++++++
.../internal/LogServiceLog4j2XmlImplTest.java | 151 +++++++++++
3 files changed, 424 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/b52309a3/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
index 9c32cfc..d0c52fb 100644
--- a/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
@@ -51,6 +51,14 @@ public class LogServiceImpl implements LogService, PaxAppender {
else if (config.get("log4j2.rootLogger.level") != null) {
return new LogServiceLog4j2Impl(config);
}
+ else if (config.get("org.ops4j.pax.logging.log4j2.config.file") != null) {
+ String file = config.get("org.ops4j.pax.logging.log4j2.config.file").toString();
+ if (file.endsWith(".xml")) {
+ return new LogServiceLog4j2XmlImpl(file);
+ } else {
+ throw new IllegalStateException("Unsupported Log4j2 configuration type: " + file);
+ }
+ }
else {
throw new IllegalStateException("Unrecognized configuration");
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b52309a3/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImpl.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImpl.java b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImpl.java
new file mode 100644
index 0000000..843bf51
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImpl.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.karaf.log.core.internal;
+
+import org.apache.karaf.log.core.Level;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class LogServiceLog4j2XmlImpl implements LogServiceInternal {
+
+ private static final String ELEMENT_LOGGERS = "Loggers";
+ private static final String ELEMENT_ROOT = "Root";
+ private static final String ELEMENT_LOGGER = "Logger";
+ private static final String ATTRIBUTE_NAME = "name";
+ private static final String ATTRIBUTE_LEVEL = "level";
+ private static final String ELEMENT_CONFIGURATION = "Configuration";
+
+ private final Path path;
+
+ LogServiceLog4j2XmlImpl(String file) {
+ this.path = Paths.get(file);
+ }
+
+ public Map<String, String> getLevel(String logger) {
+ try {
+ Document doc = loadConfig(path);
+ Map<String, Element> loggers = getLoggers(doc);
+
+ Map<String, String> levels = new TreeMap<>();
+ for (Map.Entry<String, Element> e : loggers.entrySet()) {
+ String level = e.getValue().getAttribute(ATTRIBUTE_LEVEL);
+ if (level != null && !level.isEmpty()) {
+ levels.put(e.getKey(), level);
+ }
+ }
+
+ if (ALL_LOGGER.equals(logger)) {
+ return levels;
+ }
+ String l = logger;
+ String val;
+ for (; ; ) {
+ val = levels.get(l != null ? l : ROOT_LOGGER);
+ if (val != null || l == null) {
+ return Collections.singletonMap(logger, val);
+ }
+ int idx = l.lastIndexOf('.');
+ if (idx < 0) {
+ l = null;
+ } else {
+ l = l.substring(0, idx);
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Unable to retrieve level for logger", e);
+ }
+ }
+
+ public void setLevel(String logger, String level) {
+ try {
+ Document doc = loadConfig(path);
+ Map<String, Element> loggers = getLoggers(doc);
+
+ Element element = loggers.get(logger);
+ if (element != null) {
+ if (Level.isDefault(level)) {
+ element.removeAttribute(ATTRIBUTE_LEVEL);
+ } else {
+ element.setAttribute(ATTRIBUTE_LEVEL, level);
+ }
+ }
+ else if (!Level.isDefault(level)) {
+ Element docE = doc.getDocumentElement();
+ Element docLoggers = (Element) docE.getElementsByTagName(ELEMENT_LOGGERS).item(0);
+ boolean root = ROOT_LOGGER.equals(logger);
+ if (root) {
+ element = doc.createElement(ELEMENT_ROOT);
+ element.setAttribute(ATTRIBUTE_LEVEL, level);
+ } else {
+ element = doc.createElement(ELEMENT_LOGGER);
+ element.setAttribute(ATTRIBUTE_NAME, logger);
+ element.setAttribute(ATTRIBUTE_LEVEL, level);
+ }
+ insertIndented(docLoggers, element, root);
+ } else {
+ return;
+ }
+ try (OutputStream os = Files.newOutputStream(path, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ Transformer transformer = tFactory.newTransformer();
+ transformer.transform(new DOMSource(doc), new StreamResult(os));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Unable to set level for logger", e);
+ }
+ }
+
+ /**
+ * Insert the given node at beginning or end of the given node,
+ * indenting it as needed.
+ */
+ static void insertIndented(Element loggers, Element element, boolean atBeginning) {
+ NodeList loggerElements = loggers.getElementsByTagName("*");
+ if (atBeginning && loggerElements.getLength() > 0) {
+ Node insertBefore = loggers.getFirstChild();
+ if (insertBefore != null) {
+ if (insertBefore.getNodeType() == Node.TEXT_NODE) {
+ String indent = loggers.getFirstChild().getTextContent();
+ Node node = loggers.getOwnerDocument().createTextNode(indent);
+ loggers.insertBefore(node, insertBefore);
+ }
+ loggers.insertBefore(element, insertBefore);
+ } else {
+ loggers.appendChild(element);
+ }
+ } else {
+ Node insertAfter = loggerElements.getLength() > 0 ? loggerElements.item(loggerElements.getLength() - 1) : null;
+ if (insertAfter != null) {
+ if (insertAfter.getPreviousSibling() != null && insertAfter.getPreviousSibling().getNodeType() == Node.TEXT_NODE) {
+ String indent = insertAfter.getPreviousSibling().getTextContent();
+ Node node = loggers.getOwnerDocument().createTextNode(indent);
+ if (insertAfter.getNextSibling() != null) {
+ loggers.insertBefore(node, insertAfter.getNextSibling());
+ insertAfter = node;
+ } else {
+ loggers.appendChild(node);
+ }
+ }
+ if (insertAfter.getNextSibling() != null) {
+ loggers.insertBefore(element, insertAfter.getNextSibling());
+ } else {
+ loggers.appendChild(element);
+ }
+ } else {
+ if (loggers.getPreviousSibling() != null && loggers.getPreviousSibling().getNodeType() == Node.TEXT_NODE) {
+ String indent = loggers.getPreviousSibling().getTextContent();
+ String prev = indent;
+ if (indent.endsWith("\t")) {
+ indent += "\t";
+ } else {
+ int nl = indent.lastIndexOf('\n');
+ if (nl >= 0) {
+ indent = indent + indent.substring(nl + 1);
+ } else {
+ indent += "\t";
+ }
+ }
+ if (loggers.getFirstChild() != null && loggers.getPreviousSibling().getNodeType() == Node.TEXT_NODE) {
+ loggers.removeChild(loggers.getFirstChild());
+ }
+ loggers.appendChild(loggers.getOwnerDocument().createTextNode(indent));
+ loggers.appendChild(element);
+ loggers.appendChild(loggers.getOwnerDocument().createTextNode(prev));
+ } else {
+ loggers.appendChild(element);
+ }
+ }
+ }
+
+ }
+
+ static Document loadConfig(Path path) throws Exception {
+ try (InputStream is = Files.newInputStream(path)) {
+ return loadConfig(path.toString(), is);
+ }
+ }
+
+ static Document loadConfig(String id, InputStream is) throws ParserConfigurationException, SAXException, IOException {
+ final InputSource source = new InputSource(is);
+ source.setPublicId(id);
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setValidating(false);
+ factory.setExpandEntityReferences(false);
+ setFeature(factory, "http://xml.org/sax/features/external-general-entities", false);
+ setFeature(factory, "http://xml.org/sax/features/external-parameter-entities", false);
+ setFeature(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ setFeature(factory, "http://apache.org/xml/features/xinclude/fixup-base-uris", true);
+ setFeature(factory, "http://apache.org/xml/features/xinclude/fixup-language", true);
+ tryCall(() -> factory.setXIncludeAware(true));
+ DocumentBuilder documentBuilder = factory.newDocumentBuilder();
+ return documentBuilder.parse(source);
+ }
+
+ private static void setFeature(DocumentBuilderFactory factory, String name, boolean b) {
+ tryCall(() -> factory.setFeature(name, b));
+ }
+
+ interface RunnableWithException {
+ void run() throws Exception;
+ }
+
+ private static void tryCall(RunnableWithException c) {
+ try {
+ c.run();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ private Map<String, Element> getLoggers(Document doc) {
+ Map<String, Element> loggers = new TreeMap<>();
+ Element docE = doc.getDocumentElement();
+ if (!ELEMENT_CONFIGURATION.equals(docE.getLocalName())) {
+ throw new IllegalArgumentException("Xml root document should be " + ELEMENT_CONFIGURATION);
+ }
+ NodeList children = docE.getElementsByTagName(ELEMENT_LOGGERS);
+ if (children.getLength() != 1) {
+ return Collections.emptyMap();
+ }
+ NodeList loggersList = children.item(0).getChildNodes();
+ for (int i = 0; i < loggersList.getLength(); i++) {
+ Node n = loggersList.item(i);
+ if (n instanceof Element) {
+ Element e = (Element) n;
+ if (ELEMENT_ROOT.equals(e.getLocalName())) {
+ loggers.put(ROOT_LOGGER, e);
+ } else if (ELEMENT_LOGGER.equals(e.getLocalName())) {
+ String name = e.getAttribute(ATTRIBUTE_NAME);
+ if (name != null) {
+ loggers.put(name, e);
+ }
+ }
+ }
+ }
+ return loggers;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/b52309a3/log/src/test/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImplTest.java
----------------------------------------------------------------------
diff --git a/log/src/test/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImplTest.java b/log/src/test/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImplTest.java
new file mode 100644
index 0000000..294e3f0
--- /dev/null
+++ b/log/src/test/java/org/apache/karaf/log/core/internal/LogServiceLog4j2XmlImplTest.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.karaf.log.core.internal;
+
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+
+import static org.junit.Assert.assertEquals;
+
+public class LogServiceLog4j2XmlImplTest {
+
+ @Test
+ public void testInsertIndentedTabs() throws Exception {
+ String xml = "<Configuration>\n" +
+ "\t<Loggers>\n" +
+ "\t</Loggers>\n" +
+ "</Configuration>";
+
+ String out = insertIndented(xml, false);
+ assertEquals(
+ "<Configuration>\n" +
+ "\t<Loggers>\n" +
+ "\t\t<Logger/>\n" +
+ "\t</Loggers>\n" +
+ "</Configuration>", out);
+ out = insertIndented(xml, true);
+ assertEquals(
+ "<Configuration>\n" +
+ "\t<Loggers>\n" +
+ "\t\t<Logger/>\n" +
+ "\t</Loggers>\n" +
+ "</Configuration>", out);
+ }
+
+ @Test
+ public void testInsertIndentedSpaces() throws Exception {
+ String xml = "<Configuration>\n" +
+ " <Loggers>\n" +
+ " </Loggers>\n" +
+ "</Configuration>";
+
+ String out = insertIndented(xml, false);
+ assertEquals(
+ "<Configuration>\n" +
+ " <Loggers>\n" +
+ " <Logger/>\n" +
+ " </Loggers>\n" +
+ "</Configuration>", out);
+ out = insertIndented(xml, true);
+ assertEquals(
+ "<Configuration>\n" +
+ " <Loggers>\n" +
+ " <Logger/>\n" +
+ " </Loggers>\n" +
+ "</Configuration>", out);
+ }
+
+ @Test
+ public void testInsertIndentedTabsWithRoot() throws Exception {
+ String xml = "<Configuration>\n" +
+ "\t<Loggers>\n" +
+ "\t\t<Root/>\n" +
+ "\t</Loggers>\n" +
+ "</Configuration>";
+
+ String out = insertIndented(xml, false);
+ assertEquals(
+ "<Configuration>\n" +
+ "\t<Loggers>\n" +
+ "\t\t<Root/>\n" +
+ "\t\t<Logger/>\n" +
+ "\t</Loggers>\n" +
+ "</Configuration>", out);
+ out = insertIndented(xml, true);
+ assertEquals(
+ "<Configuration>\n" +
+ "\t<Loggers>\n" +
+ "\t\t<Logger/>\n" +
+ "\t\t<Root/>\n" +
+ "\t</Loggers>\n" +
+ "</Configuration>", out);
+ }
+
+ @Test
+ public void testInsertIndentedSpacesWithRoot() throws Exception {
+ String xml = "<Configuration>\n" +
+ " <Loggers>\n" +
+ " <Root/>\n" +
+ " </Loggers>\n" +
+ "</Configuration>";
+
+ String out = insertIndented(xml, false);
+ assertEquals(
+ "<Configuration>\n" +
+ " <Loggers>\n" +
+ " <Root/>\n" +
+ " <Logger/>\n" +
+ " </Loggers>\n" +
+ "</Configuration>", out);
+ out = insertIndented(xml, true);
+ assertEquals(
+ "<Configuration>\n" +
+ " <Loggers>\n" +
+ " <Logger/>\n" +
+ " <Root/>\n" +
+ " </Loggers>\n" +
+ "</Configuration>", out);
+ }
+
+ private String insertIndented(String xml, boolean atBeginning) throws Exception {
+ Document doc = LogServiceLog4j2XmlImpl.loadConfig(null, new ByteArrayInputStream(xml.getBytes()));
+ Element element = doc.createElement("Logger");
+ LogServiceLog4j2XmlImpl.insertIndented(
+ (Element) doc.getDocumentElement().getElementsByTagName("Loggers").item(0),
+ element,
+ atBeginning);
+ try (StringWriter os = new StringWriter()) {
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ Transformer transformer = tFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.transform(new DOMSource(doc, "the.xml"), new StreamResult(os));
+ return os.toString();
+ }
+ }
+}
[2/2] karaf git commit: Fix typo in comment
Posted by gn...@apache.org.
Fix typo in comment
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/965ac924
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/965ac924
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/965ac924
Branch: refs/heads/master
Commit: 965ac924cc6547849a3d731639b583e98fe048ba
Parents: 48f26e6
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Oct 18 13:58:10 2017 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Oct 18 14:01:21 2017 +0200
----------------------------------------------------------------------
.../karaf/jaas/modules/properties/PropertiesBackingEngine.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/965ac924/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesBackingEngine.java
----------------------------------------------------------------------
diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesBackingEngine.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesBackingEngine.java
index 9435f0c..7ad3dcb 100644
--- a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesBackingEngine.java
+++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesBackingEngine.java
@@ -245,7 +245,7 @@ public class PropertiesBackingEngine implements BackingEngine {
}
}
- // nobody is using this group any more, remote it
+ // nobody is using this group any more, remove it
deleteUser(GROUP_PREFIX + group);
}