You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/06/29 21:45:42 UTC

incubator-ignite git commit: # ignite-788: init

Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-788-dev-review [created] d5f93e2b9


# ignite-788: init


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/d5f93e2b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/d5f93e2b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/d5f93e2b

Branch: refs/heads/ignite-788-dev-review
Commit: d5f93e2b9a21271b3eaeaca6b6ef5aa4d8a1c3d6
Parents: a79d2b4
Author: ashutak <as...@gridgain.com>
Authored: Mon Jun 29 22:46:27 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Mon Jun 29 22:46:27 2015 +0300

----------------------------------------------------------------------
 modules/log4j2/pom.xml                          |   5 +
 .../log4j2/Log4J2DailyRolling2FileAppender.java |  77 +++
 .../Log4J2ExternallyRolled2FileAppender.java    |  63 +++
 .../logger/log4j2/Log4J2FileAppender.java       | 107 ++++
 .../ignite/logger/log4j2/Log4J2Logger.java      | 518 +++++++++++++++++++
 .../log4j2/Log4J2Rolling2FileAppender.java      |  90 ++++
 .../ignite/logger/log4j2/Log4j2FileAware.java   |  32 ++
 .../logger/log4j2/Log4j2NodeIdFilePath.java     |  64 +++
 .../ignite/logger/log4j2/SampleClass.java       |  27 -
 .../log4j2/GridLog4j2CorrectFileNameTest.java   | 136 +++++
 .../log4j2/GridLog4j2InitializedTest.java       |  55 ++
 .../log4j2/GridLog4j2LoggingFileTest.java       |  59 +++
 .../log4j2/GridLog4j2LoggingPathTest.java       |  52 ++
 .../logger/log4j2/GridLog4j2LoggingUrlTest.java |  59 +++
 .../log4j2/GridLog4j2NotInitializedTest.java    |  46 ++
 .../testsuites/IgniteLog4j2TestSuite.java       |   5 +
 16 files changed, 1368 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/pom.xml
----------------------------------------------------------------------
diff --git a/modules/log4j2/pom.xml b/modules/log4j2/pom.xml
index 259b588..1b7ce03 100644
--- a/modules/log4j2/pom.xml
+++ b/modules/log4j2/pom.xml
@@ -41,6 +41,11 @@
         </dependency>
 
         <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-core</artifactId>
             <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2DailyRolling2FileAppender.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2DailyRolling2FileAppender.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2DailyRolling2FileAppender.java
new file mode 100644
index 0000000..31a38d4
--- /dev/null
+++ b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2DailyRolling2FileAppender.java
@@ -0,0 +1,77 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+import org.apache.log4j.*;
+
+import java.io.*;
+
+/**
+ * Log4J {@link DailyRollingFileAppender} with added support for grid node IDs.
+ */
+public class Log4J2DailyRolling2FileAppender extends DailyRollingFileAppender implements Log4j2FileAware {
+    /** Basic log file name. */
+    private String baseFileName;
+
+    /**
+     * Default constructor (does not do anything).
+     */
+    public Log4J2DailyRolling2FileAppender() {
+        init();
+    }
+
+    /**
+     * Instantiate a FileAppender with given parameters.
+     *
+     * @param layout Layout.
+     * @param filename File name.
+     * @param datePtrn Date pattern.
+     * @throws IOException If failed.
+     */
+    public Log4J2DailyRolling2FileAppender(Layout layout, String filename, String datePtrn) throws IOException {
+        super(layout, filename, datePtrn);
+
+        init();
+    }
+
+    /**
+     *
+     */
+    private void init() {
+        Log4J2Logger.addAppender(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void updateFilePath(IgniteClosure<String, String> filePathClos) {
+        A.notNull(filePathClos, "filePathClos");
+
+        if (baseFileName == null)
+            baseFileName = fileName;
+
+        fileName = filePathClos.apply(baseFileName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void setFile(String fileName, boolean fileAppend, boolean bufIO, int bufSize)
+        throws IOException {
+        if (baseFileName != null)
+            super.setFile(fileName, fileAppend, bufIO, bufSize);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2ExternallyRolled2FileAppender.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2ExternallyRolled2FileAppender.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2ExternallyRolled2FileAppender.java
new file mode 100644
index 0000000..6fbdaaf
--- /dev/null
+++ b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2ExternallyRolled2FileAppender.java
@@ -0,0 +1,63 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+import org.apache.log4j.varia.*;
+
+import java.io.*;
+
+/**
+ * Log4J {@link ExternallyRolledFileAppender} with added support for grid node IDs.
+ */
+public class Log4J2ExternallyRolled2FileAppender extends ExternallyRolledFileAppender implements Log4j2FileAware {
+    /** Basic log file name. */
+    private String baseFileName;
+
+    /**
+     * Default constructor (does not do anything).
+     */
+    public Log4J2ExternallyRolled2FileAppender() {
+        init();
+    }
+
+    /**
+     *
+     */
+    private void init() {
+        Log4J2Logger.addAppender(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void updateFilePath(IgniteClosure<String, String> filePathClos) {
+        A.notNull(filePathClos, "filePathClos");
+
+        if (baseFileName == null)
+            baseFileName = fileName;
+
+        fileName = filePathClos.apply(baseFileName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void setFile(String fileName, boolean fileAppend, boolean bufIO, int bufSize)
+        throws IOException {
+        if (baseFileName != null)
+            super.setFile(fileName, fileAppend, bufIO, bufSize);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2FileAppender.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2FileAppender.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2FileAppender.java
new file mode 100644
index 0000000..1306793
--- /dev/null
+++ b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2FileAppender.java
@@ -0,0 +1,107 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+import org.apache.log4j.*;
+
+import java.io.*;
+
+/**
+ * Log4J {@link FileAppender} with added support for grid node IDs.
+ */
+public class Log4J2FileAppender extends FileAppender implements Log4j2FileAware {
+    /** Basic log file name. */
+    private String baseFileName;
+
+    /**
+     * Default constructor (does not do anything).
+     */
+    public Log4J2FileAppender() {
+        init();
+    }
+
+    /**
+     * Instantiate a FileAppender with given parameters.
+     *
+     * @param layout Layout.
+     * @param filename File name.
+     * @throws IOException If failed.
+     */
+    public Log4J2FileAppender(Layout layout, String filename) throws IOException {
+        super(layout, filename);
+
+        init();
+    }
+
+    /**
+     * Instantiate a FileAppender with given parameters.
+     *
+     * @param layout Layout.
+     * @param filename File name.
+     * @param append Append flag.
+     * @throws IOException If failed.
+     */
+    public Log4J2FileAppender(Layout layout, String filename, boolean append) throws IOException {
+        super(layout, filename, append);
+
+        init();
+    }
+
+    /**
+     * Instantiate a FileAppender with given parameters.
+     *
+     * @param layout Layout.
+     * @param filename File name.
+     * @param append Append flag.
+     * @param bufIO Buffered IO flag.
+     * @param bufSize Buffer size.
+     * @throws IOException If failed.
+     */
+    public Log4J2FileAppender(Layout layout, String filename, boolean append, boolean bufIO, int bufSize)
+        throws IOException {
+        super(layout, filename, append, bufIO, bufSize);
+
+        init();
+    }
+
+    /**
+     *
+     */
+    private void init() {
+        Log4J2Logger.addAppender(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void setFile(String fileName, boolean fileAppend, boolean bufIO, int bufSize)
+        throws IOException {
+        if (baseFileName != null)
+            super.setFile(fileName, fileAppend, bufIO, bufSize);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void updateFilePath(IgniteClosure<String, String> filePathClos) {
+        A.notNull(filePathClos, "filePathClos");
+
+        if (baseFileName == null)
+            baseFileName = fileName;
+
+        fileName = filePathClos.apply(baseFileName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Logger.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Logger.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Logger.java
new file mode 100644
index 0000000..6c37e8a
--- /dev/null
+++ b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Logger.java
@@ -0,0 +1,518 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import org.apache.ignite.*;
+import org.apache.ignite.internal.util.*;
+import org.apache.ignite.internal.util.tostring.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.logger.*;
+import org.apache.log4j.*;
+import org.apache.log4j.varia.*;
+import org.apache.log4j.xml.*;
+import org.jetbrains.annotations.*;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import static org.apache.ignite.IgniteSystemProperties.*;
+
+/**
+ * Log4j-based implementation for logging. This logger should be used
+ * by loaders that have prefer <a target=_new href="http://logging.apache.org/log4j/docs/">log4j</a>-based logging.
+ * <p>
+ * Here is a typical example of configuring log4j logger in Ignite configuration file:
+ * <pre name="code" class="xml">
+ *      &lt;property name="gridLogger"&gt;
+ *          &lt;bean class="org.apache.ignite.grid.logger.log4j.GridLog4jLogger"&gt;
+ *              &lt;constructor-arg type="java.lang.String" value="config/ignite-log4j.xml"/&gt;
+ *          &lt;/bean>
+ *      &lt;/property&gt;
+ * </pre>
+ * and from your code:
+ * <pre name="code" class="java">
+ *      IgniteConfiguration cfg = new IgniteConfiguration();
+ *      ...
+ *      URL xml = U.resolveIgniteUrl("config/custom-log4j.xml");
+ *      IgniteLogger log = new Log4JLogger(xml);
+ *      ...
+ *      cfg.setGridLogger(log);
+ * </pre>
+ *
+ * Please take a look at <a target=_new href="http://logging.apache.org/log4j/1.2/index.html">Apache Log4j 1.2</a>
+ * for additional information.
+ * <p>
+ * It's recommended to use Ignite logger injection instead of using/instantiating
+ * logger in your task/job code. See {@link org.apache.ignite.resources.LoggerResource} annotation about logger
+ * injection.
+ */
+public class Log4J2Logger implements IgniteLogger, LoggerNodeIdAware, Log4j2FileAware {
+    /** Appenders. */
+    private static Collection<FileAppender> fileAppenders = new GridConcurrentHashSet<>();
+
+    /** */
+    private static volatile boolean inited;
+
+    /** */
+    private static volatile boolean quiet0;
+
+    /** */
+    private static final Object mux = new Object();
+
+    /** Logger implementation. */
+    @GridToStringExclude
+    @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
+    private Logger impl;
+
+    /** Path to configuration file. */
+    private final String path;
+
+    /** Quiet flag. */
+    private final boolean quiet;
+
+    /** Node ID. */
+    private UUID nodeId;
+
+    /**
+     * Creates new logger and automatically detects if root logger already
+     * has appenders configured. If it does not, the root logger will be
+     * configured with default appender (analogous to calling
+     * {@link #Log4J2Logger(boolean) Log4JLogger(boolean)}
+     * with parameter {@code true}, otherwise, existing appenders will be used (analogous
+     * to calling {@link #Log4J2Logger(boolean) Log4JLogger(boolean)}
+     * with parameter {@code false}).
+     */
+    public Log4J2Logger() {
+        this(!isConfigured());
+    }
+
+    /**
+     * Creates new logger. If initialize parameter is {@code true} the Log4j
+     * logger will be initialized with default console appender and {@code INFO}
+     * log level.
+     *
+     * @param init If {@code true}, then a default console appender with
+     *      following pattern layout will be created: {@code %d{ABSOLUTE} %-5p [%c{1}] %m%n}.
+     *      If {@code false}, then no implicit initialization will take place,
+     *      and {@code Log4j} should be configured prior to calling this
+     *      constructor.
+     */
+    public Log4J2Logger(boolean init) {
+        impl = Logger.getRootLogger();
+
+        if (init) {
+            // Implementation has already been inited, passing NULL.
+            addConsoleAppenderIfNeeded(Level.INFO, null);
+
+            quiet = quiet0;
+        }
+        else
+            quiet = true;
+
+        path = null;
+    }
+
+    /**
+     * Creates new logger with given implementation.
+     *
+     * @param impl Log4j implementation to use.
+     */
+    public Log4J2Logger(final Logger impl) {
+        assert impl != null;
+
+        path = null;
+
+        addConsoleAppenderIfNeeded(null, new C1<Boolean, Logger>() {
+            @Override public Logger apply(Boolean init) {
+                return impl;
+            }
+        });
+
+        quiet = quiet0;
+    }
+
+    /**
+     * Creates new logger with given configuration {@code path}.
+     *
+     * @param path Path to log4j configuration XML file.
+     * @throws IgniteCheckedException Thrown in case logger can't be created.
+     */
+    public Log4J2Logger(String path) throws IgniteCheckedException {
+        if (path == null)
+            throw new IgniteCheckedException("Configuration XML file for Log4j must be specified.");
+
+        this.path = path;
+
+        final URL cfgUrl = U.resolveIgniteUrl(path);
+
+        if (cfgUrl == null)
+            throw new IgniteCheckedException("Log4j configuration path was not found: " + path);
+
+        addConsoleAppenderIfNeeded(null, new C1<Boolean, Logger>() {
+            @Override public Logger apply(Boolean init) {
+                if (init)
+                    DOMConfigurator.configure(cfgUrl);
+
+                return Logger.getRootLogger();
+            }
+        });
+
+        quiet = quiet0;
+    }
+
+    /**
+     * Creates new logger with given configuration {@code cfgFile}.
+     *
+     * @param cfgFile Log4j configuration XML file.
+     * @throws IgniteCheckedException Thrown in case logger can't be created.
+     */
+    public Log4J2Logger(File cfgFile) throws IgniteCheckedException {
+        if (cfgFile == null)
+            throw new IgniteCheckedException("Configuration XML file for Log4j must be specified.");
+
+        if (!cfgFile.exists() || cfgFile.isDirectory())
+            throw new IgniteCheckedException("Log4j configuration path was not found or is a directory: " + cfgFile);
+
+        path = cfgFile.getAbsolutePath();
+
+        addConsoleAppenderIfNeeded(null, new C1<Boolean, Logger>() {
+            @Override public Logger apply(Boolean init) {
+                if (init)
+                    DOMConfigurator.configure(path);
+
+                return Logger.getRootLogger();
+            }
+        });
+
+        quiet = quiet0;
+    }
+
+    /**
+     * Creates new logger with given configuration {@code cfgUrl}.
+     *
+     * @param cfgUrl URL for Log4j configuration XML file.
+     * @throws IgniteCheckedException Thrown in case logger can't be created.
+     */
+    public Log4J2Logger(final URL cfgUrl) throws IgniteCheckedException {
+        if (cfgUrl == null)
+            throw new IgniteCheckedException("Configuration XML file for Log4j must be specified.");
+
+        path = null;
+
+        addConsoleAppenderIfNeeded(null, new C1<Boolean, Logger>() {
+            @Override public Logger apply(Boolean init) {
+                if (init)
+                    DOMConfigurator.configure(cfgUrl);
+
+                return Logger.getRootLogger();
+            }
+        });
+
+        quiet = quiet0;
+    }
+
+    /**
+     * Checks if Log4j is already configured within this VM or not.
+     *
+     * @return {@code True} if log4j was already configured, {@code false} otherwise.
+     */
+    public static boolean isConfigured() {
+        return Logger.getRootLogger().getAllAppenders().hasMoreElements();
+    }
+
+    /**
+     * Sets level for internal log4j implementation.
+     *
+     * @param level Log level to set.
+     */
+    public void setLevel(Level level) {
+        impl.setLevel(level);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public String fileName() {
+        FileAppender fapp = F.first(fileAppenders);
+
+        return fapp != null ? fapp.getFile() : null;
+    }
+
+    /**
+     * Adds console appender when needed with some default logging settings.
+     *
+     * @param logLevel Optional log level.
+     * @param implInitC Optional log implementation init closure.
+     */
+    private void addConsoleAppenderIfNeeded(@Nullable Level logLevel,
+        @Nullable IgniteClosure<Boolean, Logger> implInitC) {
+        if (inited) {
+            if (implInitC != null)
+                // Do not init.
+                impl = implInitC.apply(false);
+
+            return;
+        }
+
+        synchronized (mux) {
+            if (inited) {
+                if (implInitC != null)
+                    // Do not init.
+                    impl = implInitC.apply(false);
+
+                return;
+            }
+
+            if (implInitC != null)
+                // Init logger impl.
+                impl = implInitC.apply(true);
+
+            boolean quiet = Boolean.valueOf(System.getProperty(IGNITE_QUIET, "true"));
+
+            boolean consoleAppenderFound = false;
+            Category rootCategory = null;
+            ConsoleAppender errAppender = null;
+
+            for (Category l = impl; l != null; ) {
+                if (!consoleAppenderFound) {
+                    for (Enumeration appenders = l.getAllAppenders(); appenders.hasMoreElements(); ) {
+                        Appender appender = (Appender)appenders.nextElement();
+
+                        if (appender instanceof ConsoleAppender) {
+                            if ("CONSOLE_ERR".equals(appender.getName())) {
+                                // Treat CONSOLE_ERR appender as a system one and don't count it.
+                                errAppender = (ConsoleAppender)appender;
+
+                                continue;
+                            }
+
+                            consoleAppenderFound = true;
+
+                            break;
+                        }
+                    }
+                }
+
+                if (l.getParent() == null) {
+                    rootCategory = l;
+
+                    break;
+                }
+                else
+                    l = l.getParent();
+            }
+
+            if (consoleAppenderFound && quiet)
+                // User configured console appender, but log is quiet.
+                quiet = false;
+
+            if (!consoleAppenderFound && !quiet && Boolean.valueOf(System.getProperty(IGNITE_CONSOLE_APPENDER, "true"))) {
+                // Console appender not found => we've looked through all categories up to root.
+                assert rootCategory != null;
+
+                // User launched ignite in verbose mode and did not add console appender with INFO level
+                // to configuration and did not set IGNITE_CONSOLE_APPENDER to false.
+                if (errAppender != null) {
+                    rootCategory.addAppender(createConsoleAppender(Level.INFO));
+
+                    if (errAppender.getThreshold() == Level.ERROR)
+                        errAppender.setThreshold(Level.WARN);
+                }
+                else
+                    // No error console appender => create console appender with no level limit.
+                    rootCategory.addAppender(createConsoleAppender(Level.OFF));
+
+                if (logLevel != null)
+                    impl.setLevel(logLevel);
+            }
+
+            quiet0 = quiet;
+            inited = true;
+        }
+    }
+
+    /**
+     * Creates console appender with some reasonable default logging settings.
+     *
+     * @param maxLevel Max logging level.
+     * @return New console appender.
+     */
+    private Appender createConsoleAppender(Level maxLevel) {
+        String fmt = "[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n";
+
+        // Configure output that should go to System.out
+        Appender app = new ConsoleAppender(new PatternLayout(fmt), ConsoleAppender.SYSTEM_OUT);
+
+        LevelRangeFilter lvlFilter = new LevelRangeFilter();
+
+        lvlFilter.setLevelMin(Level.TRACE);
+        lvlFilter.setLevelMax(maxLevel);
+
+        app.addFilter(lvlFilter);
+
+        return app;
+    }
+
+    /**
+     * Adds file appender.
+     *
+     * @param a Appender.
+     */
+    public static void addAppender(FileAppender a) {
+        A.notNull(a, "a");
+
+        fileAppenders.add(a);
+    }
+
+    /**
+     * Removes file appender.
+     *
+     * @param a Appender.
+     */
+    public static void removeAppender(FileAppender a) {
+        A.notNull(a, "a");
+
+        fileAppenders.remove(a);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void setNodeId(UUID nodeId) {
+        A.notNull(nodeId, "nodeId");
+
+        this.nodeId = nodeId;
+
+        updateFilePath(new Log4j2NodeIdFilePath(nodeId));
+    }
+
+    /** {@inheritDoc} */
+    @Override public UUID getNodeId() {
+        return nodeId;
+    }
+
+    /**
+     * Gets files for all registered file appenders.
+     *
+     * @return List of files.
+     */
+    public static Collection<String> logFiles() {
+        Collection<String> res = new ArrayList<>(fileAppenders.size());
+
+        for (FileAppender a : fileAppenders)
+            res.add(a.getFile());
+
+        return res;
+    }
+
+    /**
+     * Gets {@link org.apache.ignite.IgniteLogger} wrapper around log4j logger for the given
+     * category. If category is {@code null}, then root logger is returned. If
+     * category is an instance of {@link Class} then {@code (Class)ctgr).getName()}
+     * is used as category name.
+     *
+     * @param ctgr {@inheritDoc}
+     * @return {@link org.apache.ignite.IgniteLogger} wrapper around log4j logger.
+     */
+    @Override public Log4J2Logger getLogger(Object ctgr) {
+        return new Log4J2Logger(ctgr == null ? Logger.getRootLogger() :
+            ctgr instanceof Class ? Logger.getLogger(((Class<?>)ctgr).getName()) :
+                Logger.getLogger(ctgr.toString()));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void trace(String msg) {
+        if (!impl.isTraceEnabled())
+            warning("Logging at TRACE level without checking if TRACE level is enabled: " + msg);
+
+        impl.trace(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void debug(String msg) {
+        if (!impl.isDebugEnabled())
+            warning("Logging at DEBUG level without checking if DEBUG level is enabled: " + msg);
+
+        impl.debug(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void info(String msg) {
+        if (!impl.isInfoEnabled())
+            warning("Logging at INFO level without checking if INFO level is enabled: " + msg);
+
+        impl.info(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void warning(String msg) {
+        impl.warn(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void warning(String msg, @Nullable Throwable e) {
+        impl.warn(msg, e);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void error(String msg) {
+        impl.error(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void error(String msg, @Nullable Throwable e) {
+        impl.error(msg, e);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isTraceEnabled() {
+        return impl.isTraceEnabled();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDebugEnabled() {
+        return impl.isDebugEnabled();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isInfoEnabled() {
+        return impl.isInfoEnabled();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isQuiet() {
+        return quiet;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(Log4J2Logger.class, this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void updateFilePath(IgniteClosure<String, String> filePathClos) {
+        A.notNull(filePathClos, "filePathClos");
+
+        for (FileAppender a : fileAppenders) {
+            if (a instanceof Log4j2FileAware) {
+                ((Log4j2FileAware)a).updateFilePath(filePathClos);
+
+                a.activateOptions();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Rolling2FileAppender.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Rolling2FileAppender.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Rolling2FileAppender.java
new file mode 100644
index 0000000..5306bef
--- /dev/null
+++ b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4J2Rolling2FileAppender.java
@@ -0,0 +1,90 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+import org.apache.log4j.*;
+
+import java.io.*;
+
+/**
+ * Log4J {@link RollingFileAppender} with added support for grid node IDs.
+ */
+public class Log4J2Rolling2FileAppender extends RollingFileAppender implements Log4j2FileAware {
+    /** Basic log file name. */
+    private String baseFileName;
+
+    /**
+     * Default constructor (does not do anything).
+     */
+    public Log4J2Rolling2FileAppender() {
+        init();
+    }
+
+    /**
+     * Instantiate a FileAppender with given parameters.
+     *
+     * @param layout Layout.
+     * @param filename File name.
+     * @throws IOException If failed.
+     */
+    public Log4J2Rolling2FileAppender(Layout layout, String filename) throws IOException {
+        super(layout, filename);
+
+        init();
+    }
+
+    /**
+     * Instantiate a FileAppender with given parameters.
+     *
+     * @param layout Layout.
+     * @param filename File name.
+     * @param append Append flag.
+     * @throws IOException If failed.
+     */
+    public Log4J2Rolling2FileAppender(Layout layout, String filename, boolean append) throws IOException {
+        super(layout, filename, append);
+
+        init();
+    }
+
+    /**
+     * Initializes appender.
+     */
+    private void init() {
+        Log4J2Logger.addAppender(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void updateFilePath(IgniteClosure<String, String> filePathClos) {
+        A.notNull(filePathClos, "filePathClos");
+
+        if (baseFileName == null)
+            baseFileName = fileName;
+
+        fileName = filePathClos.apply(baseFileName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void setFile(String fileName, boolean fileAppend, boolean bufIO, int bufSize)
+        throws IOException {
+        if (baseFileName != null)
+            super.setFile(fileName, fileAppend, bufIO, bufSize);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2FileAware.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2FileAware.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2FileAware.java
new file mode 100644
index 0000000..de261aa
--- /dev/null
+++ b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2FileAware.java
@@ -0,0 +1,32 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import org.apache.ignite.lang.*;
+
+/**
+ * Interface for those loggers and appenders that evaluate their file paths lazily.
+ */
+interface Log4j2FileAware {
+    /**
+     * Sets closure that later evaluate file path.
+     *
+     * @param filePathClos Closure that generates actual file path.
+     */
+    void updateFilePath(IgniteClosure<String, String> filePathClos);
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2NodeIdFilePath.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2NodeIdFilePath.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2NodeIdFilePath.java
new file mode 100644
index 0000000..a0a7b12
--- /dev/null
+++ b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/Log4j2NodeIdFilePath.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import org.apache.ignite.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Closure that generates file path adding node id to filename as a suffix.
+ */
+class Log4j2NodeIdFilePath implements IgniteClosure<String, String> {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Node id. */
+    private final UUID nodeId;
+
+    /**
+     * Creates new instance.
+     *
+     * @param id Node id.
+     */
+    Log4j2NodeIdFilePath(UUID id) {
+        nodeId = id;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String apply(String oldPath) {
+        if (!F.isEmpty(U.IGNITE_LOG_DIR))
+            return U.nodeIdLogFileName(nodeId, new File(U.IGNITE_LOG_DIR, "ignite.log").getAbsolutePath());
+
+        if (oldPath != null) // fileName could be null if IGNITE_HOME is not defined.
+            return U.nodeIdLogFileName(nodeId, oldPath);
+
+        String tmpDir = IgniteSystemProperties.getString("java.io.tmpdir");
+
+        if (tmpDir != null)
+            return U.nodeIdLogFileName(nodeId, new File(tmpDir, "ignite.log").getAbsolutePath());
+
+        System.err.println("Failed to get tmp directory for log file.");
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/SampleClass.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/SampleClass.java b/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/SampleClass.java
deleted file mode 100644
index 8fdc2f1..0000000
--- a/modules/log4j2/src/main/java/org/apache/ignite/logger/log4j2/SampleClass.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.ignite.logger.log4j2;
-
-/**
- * TODO: delete me.
- *
- * This class was added just to resolve problem with javadocs for empty module.
- * Class have to be deleted if there are another files in module.
- */
-public class SampleClass {
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2CorrectFileNameTest.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2CorrectFileNameTest.java b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2CorrectFileNameTest.java
new file mode 100644
index 0000000..d1a96c7
--- /dev/null
+++ b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2CorrectFileNameTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import junit.framework.*;
+import org.apache.ignite.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.testframework.junits.common.*;
+import org.apache.log4j.*;
+import org.apache.log4j.varia.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Tests that several grids log to files with correct names.
+ */
+@GridCommonTest(group = "Logger")
+public class GridLog4j2CorrectFileNameTest extends TestCase {
+    /** Appender */
+    private Log4J2Rolling2FileAppender appender;
+
+    /** {@inheritDoc} */
+    @Override protected void setUp() throws Exception {
+        Logger root = Logger.getRootLogger();
+
+        for (Enumeration appenders = root.getAllAppenders(); appenders.hasMoreElements(); ) {
+            if (appenders.nextElement() instanceof Log4J2Rolling2FileAppender)
+                return;
+        }
+
+        appender = createAppender();
+
+        root.addAppender(appender);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void tearDown() {
+        if (appender != null) {
+            Logger.getRootLogger().removeAppender(Log4J2Rolling2FileAppender.class.getSimpleName());
+
+            Log4J2Logger.removeAppender(appender);
+        }
+    }
+
+    /**
+     * Tests correct behaviour in case 2 local nodes are started.
+     *
+     * @throws Exception If error occurs.
+     */
+    public void testLogFilesTwoNodes() throws Exception {
+        checkOneNode(0);
+        checkOneNode(1);
+    }
+
+    /**
+     * Starts the local node and checks for presence of log file.
+     * Also checks that this is really a log of a started node.
+     *
+     * @param id Test-local node ID.
+     * @throws Exception If error occurred.
+     */
+    private void checkOneNode(int id) throws Exception {
+        try (Ignite ignite = G.start(getConfiguration("grid" + id))) {
+            String id8 = U.id8(ignite.cluster().localNode().id());
+            String logPath = "work/log/ignite-" + id8 + ".log";
+            File logFile = U.resolveIgnitePath(logPath);
+
+            assertNotNull("Failed to resolve path: " + logPath, logFile);
+            assertTrue("Log file does not exist: " + logFile, logFile.exists());
+
+            String logContent = U.readFileToString(logFile.getAbsolutePath(), "UTF-8");
+
+            assertTrue("Log file does not contain it's node ID: " + logFile,
+                logContent.contains(">>> Local node [ID=" + id8.toUpperCase()));
+        }
+    }
+
+    /**
+     * Creates grid configuration.
+     *
+     * @param gridName Grid name.
+     * @return Grid configuration.
+     * @throws Exception If error occurred.
+     */
+    private static IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setGridName(gridName);
+        cfg.setGridLogger(new Log4J2Logger());
+        cfg.setConnectorConfiguration(null);
+
+        return cfg;
+    }
+
+    /**
+     * Creates new GridLog4jRollingFileAppender.
+     *
+     * @return GridLog4jRollingFileAppender.
+     * @throws Exception If error occurred.
+     */
+    private static Log4J2Rolling2FileAppender createAppender() throws Exception {
+        Log4J2Rolling2FileAppender appender = new Log4J2Rolling2FileAppender();
+
+        appender.setLayout(new PatternLayout("[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n"));
+        appender.setFile("work/log/ignite.log");
+        appender.setName(Log4J2Rolling2FileAppender.class.getSimpleName());
+
+        LevelRangeFilter lvlFilter = new LevelRangeFilter();
+
+        lvlFilter.setLevelMin(Level.DEBUG);
+        lvlFilter.setLevelMax(Level.INFO);
+
+        appender.addFilter(lvlFilter);
+
+        return appender;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2InitializedTest.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2InitializedTest.java b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2InitializedTest.java
new file mode 100644
index 0000000..49ecfe7
--- /dev/null
+++ b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2InitializedTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import junit.framework.*;
+import org.apache.ignite.*;
+import org.apache.ignite.testframework.junits.common.*;
+import org.apache.log4j.*;
+
+/**
+ * Log4j initialized test.
+ */
+@GridCommonTest(group = "Logger")
+public class GridLog4j2InitializedTest extends TestCase {
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Override protected void setUp() throws Exception {
+        BasicConfigurator.configure();
+    }
+
+    /** */
+    public void testLogInitialize() {
+        IgniteLogger log = new Log4J2Logger();
+
+        assert log.isInfoEnabled() == true;
+
+        if (log.isDebugEnabled())
+            log.debug("This is 'debug' message.");
+
+        log.info("This is 'info' message.");
+        log.warning("This is 'warning' message.");
+        log.warning("This is 'warning' message.", new Exception("It's a test warning exception"));
+        log.error("This is 'error' message.");
+        log.error("This is 'error' message.", new Exception("It's a test error exception"));
+
+        assert log.getLogger(GridLog4j2InitializedTest.class.getName()) instanceof Log4J2Logger;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingFileTest.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingFileTest.java b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingFileTest.java
new file mode 100644
index 0000000..9c34993
--- /dev/null
+++ b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingFileTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import junit.framework.*;
+import org.apache.ignite.*;
+import org.apache.ignite.testframework.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import java.io.*;
+
+/**
+ * Grid Log4j SPI test.
+ */
+@GridCommonTest(group = "Logger")
+public class GridLog4j2LoggingFileTest extends TestCase {
+    /** */
+    private IgniteLogger log;
+
+    /** {@inheritDoc} */
+    @Override protected void setUp() throws Exception {
+        File xml = GridTestUtils.resolveIgnitePath("modules/core/src/test/config/log4j-test.xml");
+
+        assert xml != null;
+        assert xml.exists() == true;
+
+        log = new Log4J2Logger(xml).getLogger(getClass());
+    }
+
+    /**
+     * Tests log4j logging SPI.
+     */
+    public void testLog() {
+        assert log.isDebugEnabled() == true;
+        assert log.isInfoEnabled() == true;
+
+        log.debug("This is 'debug' message.");
+        log.info("This is 'info' message.");
+        log.warning("This is 'warning' message.");
+        log.warning("This is 'warning' message.", new Exception("It's a test warning exception"));
+        log.error("This is 'error' message.");
+        log.error("This is 'error' message.", new Exception("It's a test error exception"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingPathTest.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingPathTest.java b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingPathTest.java
new file mode 100644
index 0000000..87f6dd6
--- /dev/null
+++ b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingPathTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import junit.framework.*;
+import org.apache.ignite.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+/**
+ * Grid Log4j SPI test.
+ */
+@GridCommonTest(group = "Logger")
+public class GridLog4j2LoggingPathTest extends TestCase {
+    /** */
+    private IgniteLogger log;
+
+    /** {@inheritDoc} */
+    @Override protected void setUp() throws Exception {
+        log = new Log4J2Logger("modules/core/src/test/config/log4j-test.xml").getLogger(getClass());
+    }
+
+    /**
+     * Tests log4j logging SPI.
+     */
+    public void testLog() {
+        assert log.isInfoEnabled() == true;
+
+        if (log.isDebugEnabled())
+            log.debug("This is 'debug' message.");
+
+        log.info("This is 'info' message.");
+        log.warning("This is 'warning' message.");
+        log.warning("This is 'warning' message.", new Exception("It's a test warning exception"));
+        log.error("This is 'error' message.");
+        log.error("This is 'error' message.", new Exception("It's a test error exception"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingUrlTest.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingUrlTest.java b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingUrlTest.java
new file mode 100644
index 0000000..b0b62ab
--- /dev/null
+++ b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2LoggingUrlTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import junit.framework.*;
+import org.apache.ignite.*;
+import org.apache.ignite.testframework.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import java.io.*;
+
+/**
+ * Grid Log4j SPI test.
+ */
+@GridCommonTest(group = "Logger")
+public class GridLog4j2LoggingUrlTest extends TestCase {
+    /** */
+    private IgniteLogger log;
+
+    /** {@inheritDoc} */
+    @Override protected void setUp() throws Exception {
+        File xml = GridTestUtils.resolveIgnitePath("modules/core/src/test/config/log4j-test.xml");
+
+        assert xml != null;
+        assert xml.exists();
+
+        log = new Log4J2Logger(xml.toURI().toURL()).getLogger(getClass());
+    }
+
+    /**
+     * Tests log4j logging SPI.
+     */
+    public void testLog() {
+        assert log.isDebugEnabled();
+        assert log.isInfoEnabled();
+
+        log.debug("This is 'debug' message.");
+        log.info("This is 'info' message.");
+        log.warning("This is 'warning' message.");
+        log.warning("This is 'warning' message.", new Exception("It's a test warning exception"));
+        log.error("This is 'error' message.");
+        log.error("This is 'error' message.", new Exception("It's a test error exception"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2NotInitializedTest.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2NotInitializedTest.java b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2NotInitializedTest.java
new file mode 100644
index 0000000..6db58bf
--- /dev/null
+++ b/modules/log4j2/src/test/java/org/apache/ignite/logger/log4j2/GridLog4j2NotInitializedTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.ignite.logger.log4j2;
+
+import junit.framework.*;
+import org.apache.ignite.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+/**
+ * Log4j not initialized test.
+ */
+@GridCommonTest(group = "Logger")
+public class GridLog4j2NotInitializedTest extends TestCase {
+    /** */
+    public void testLogInitialize() {
+        IgniteLogger log = new Log4J2Logger().getLogger(GridLog4j2NotInitializedTest.class);
+
+        if (log.isDebugEnabled())
+            log.debug("This is 'debug' message.");
+        else
+            System.out.println("DEBUG level is not enabled.");
+
+        if (log.isInfoEnabled())
+            log.info("This is 'info' message.");
+        else
+            System.out.println("INFO level is not enabled.");
+
+        log.warning("This is 'warning' message.");
+        log.error("This is 'error' message.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d5f93e2b/modules/log4j2/src/test/java/org/apache/ignite/testsuites/IgniteLog4j2TestSuite.java
----------------------------------------------------------------------
diff --git a/modules/log4j2/src/test/java/org/apache/ignite/testsuites/IgniteLog4j2TestSuite.java b/modules/log4j2/src/test/java/org/apache/ignite/testsuites/IgniteLog4j2TestSuite.java
index 23fef9a..1627f5b 100644
--- a/modules/log4j2/src/test/java/org/apache/ignite/testsuites/IgniteLog4j2TestSuite.java
+++ b/modules/log4j2/src/test/java/org/apache/ignite/testsuites/IgniteLog4j2TestSuite.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.testsuites;
 
 import junit.framework.*;
+import org.apache.ignite.logger.log4j2.*;
 
 /**
  * Log4j2 logging tests.
@@ -30,6 +31,10 @@ public class IgniteLog4j2TestSuite extends TestSuite {
     public static TestSuite suite() throws Exception {
         TestSuite suite = new TestSuite("Log4j2 Logging Test Suite");
 
+        suite.addTest(new TestSuite(GridLog4j2InitializedTest.class));
+        suite.addTest(new TestSuite(GridLog4j2NotInitializedTest.class));
+        suite.addTest(new TestSuite(GridLog4j2CorrectFileNameTest.class));
+
         return suite;
     }
 }