You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2023/01/16 16:23:16 UTC

[sis] branch geoapi-4.0 updated: Use static constants for most (not all) loggers.

This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 8566937622 Use static constants for most (not all) loggers.
8566937622 is described below

commit 85669376228938c26c46ae31ac5d9e8dc154f35d
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Mon Jan 16 17:22:35 2023 +0100

    Use static constants for most (not all) loggers.
    
    https://issues.apache.org/jira/browse/SIS-570
---
 .../java/org/apache/sis/console/AboutCommand.java  |  4 +-
 .../java/org/apache/sis/console/package-info.java  |  2 +-
 .../apache/sis/gui/coverage/CoverageCanvas.java    |  7 ++-
 .../apache/sis/gui/coverage/GridSliceSelector.java |  8 ++--
 .../org/apache/sis/gui/dataset/FeatureTable.java   |  9 ++--
 .../org/apache/sis/gui/dataset/ResourceTree.java   |  9 ++--
 .../org/apache/sis/gui/dataset/WindowHandler.java  |  8 ++--
 .../org/apache/sis/gui/map/GestureFollower.java    |  8 ++--
 .../java/org/apache/sis/gui/map/MapCanvas.java     |  7 ++-
 .../org/apache/sis/gui/map/OperationFinder.java    |  7 ++-
 .../java/org/apache/sis/gui/map/StatusBar.java     |  6 +--
 .../org/apache/sis/gui/map/ValuesFormatter.java    |  7 ++-
 .../org/apache/sis/gui/metadata/MetadataTree.java  |  7 ++-
 .../org/apache/sis/gui/metadata/package-info.java  |  2 +-
 .../apache/sis/gui/referencing/AuthorityCodes.java |  7 ++-
 .../gui/referencing/PositionableProjection.java    |  8 ++--
 .../gui/referencing/RecentReferenceSystems.java    |  7 ++-
 .../java/org/apache/sis/gui/referencing/Utils.java |  7 ++-
 .../apache/sis/internal/gui/BackgroundThreads.java |  7 ++-
 .../apache/sis/internal/gui/ImageConverter.java    |  7 ++-
 .../org/apache/sis/internal/gui/LogHandler.java    |  8 +++-
 .../java/org/apache/sis/internal/gui/Styles.java   |  7 ++-
 .../org/apache/sis/internal/gui/package-info.java  |  2 +-
 .../coverage/grid/CoordinateOperationFinder.java   |  7 +--
 .../apache/sis/coverage/grid/DefaultEvaluator.java |  7 +--
 .../sis/coverage/grid/GridCoverageProcessor.java   |  7 +--
 .../org/apache/sis/coverage/grid/GridExtent.java   | 11 +++--
 .../org/apache/sis/coverage/grid/GridGeometry.java |  4 +-
 .../apache/sis/feature/AbstractIdentifiedType.java |  9 +++-
 .../java/org/apache/sis/feature/FeatureFormat.java |  7 +--
 .../java/org/apache/sis/feature/package-info.java  |  2 +-
 .../apache/sis/image/BandedSampleConverter.java    |  7 ++-
 .../java/org/apache/sis/image/ErrorAction.java     | 13 +++--
 .../main/java/org/apache/sis/image/MaskImage.java  |  7 ++-
 .../java/org/apache/sis/image/ResampledImage.java  |  7 ++-
 .../java/org/apache/sis/image/package-info.java    |  2 +-
 .../sis/internal/coverage/j2d/ImageUtilities.java  | 11 +++--
 .../apache/sis/internal/feature/Geometries.java    |  9 +++-
 .../sis/internal/feature/GeometryFactories.java    |  6 +--
 .../org/apache/sis/internal/feature/jts/JTS.java   |  7 ++-
 .../sis/internal/feature/jts/package-info.java     |  2 +-
 .../apache/sis/internal/feature/package-info.java  |  2 +-
 .../java/org/apache/sis/internal/filter/Node.java  | 12 +++--
 .../internal/filter/sqlmm/RegistryTestCase.java    |  8 ++--
 .../apache/sis/internal/metadata/Dependencies.java |  3 +-
 .../sis/internal/metadata/ServicesForUtility.java  |  8 ++--
 .../sis/internal/metadata/sql/Initializer.java     | 28 ++++++-----
 .../sis/internal/metadata/sql/LocalDataSource.java | 14 +++---
 .../sis/internal/metadata/sql/package-info.java    |  2 +-
 .../sis/internal/simple/CitationConstant.java      | 12 +++--
 .../apache/sis/internal/simple/package-info.java   |  2 +-
 .../apache/sis/metadata/PropertyInformation.java   | 11 ++---
 .../sis/metadata/StandardImplementation.java       | 11 +++--
 .../java/org/apache/sis/metadata/package-info.java |  2 +-
 .../apache/sis/metadata/sql/MetadataSource.java    |  7 ++-
 .../org/apache/sis/metadata/sql/package-info.java  |  2 +-
 .../main/java/org/apache/sis/util/iso/Types.java   | 18 +++----
 .../main/java/org/apache/sis/xml/LegacyCodes.java  |  8 ++--
 .../java/org/apache/sis/xml/MarshallerPool.java    | 10 ++--
 .../src/main/java/org/apache/sis/xml/XLink.java    |  8 ++--
 .../sis/internal/map/coverage/RenderingData.java   | 12 +++--
 .../sis/internal/map/coverage/package-info.java    |  2 +-
 .../main/java/org/apache/sis/portrayal/Canvas.java |  5 +-
 .../org/apache/sis/portrayal/CanvasFollower.java   |  4 +-
 .../java/org/apache/sis/portrayal/Observable.java  |  9 +++-
 .../apache/sis/portrayal/TransformChangeEvent.java |  4 +-
 .../gazetteer/MilitaryGridReferenceSystem.java     |  8 +---
 .../gazetteer/ReferencingByIdentifiers.java        | 12 ++++-
 .../sis/referencing/gazetteer/package-info.java    |  2 +-
 .../org/apache/sis/geometry/CoordinateFormat.java  | 14 ++++--
 .../java/org/apache/sis/geometry/Envelopes.java    | 13 +++--
 .../apache/sis/geometry/WraparoundAdjustment.java  |  6 +--
 .../java/org/apache/sis/geometry/package-info.java |  2 +-
 .../internal/referencing/DefinitionVerifier.java   |  2 +-
 .../sis/internal/referencing/WKTKeywords.java      |  6 +--
 .../sis/internal/referencing/WKTUtilities.java     |  9 +++-
 .../referencing/provider/AbstractProvider.java     | 12 +++--
 .../referencing/provider/DatumShiftGridLoader.java | 15 +++---
 .../provider/FranceGeocentricInterpolation.java    |  6 +--
 .../referencing/provider/GeocentricAffine.java     |  7 +--
 .../java/org/apache/sis/io/wkt/AbstractParser.java | 14 ++++--
 .../main/java/org/apache/sis/io/wkt/WKTFormat.java | 16 ++++---
 .../sis/parameter/DefaultParameterValue.java       | 12 +++--
 .../java/org/apache/sis/parameter/Verifier.java    |  8 ++--
 .../org/apache/sis/parameter/package-info.java     |  2 +-
 .../apache/sis/referencing/AuthorityFactories.java | 11 +++--
 .../main/java/org/apache/sis/referencing/CRS.java  | 12 +++--
 .../java/org/apache/sis/referencing/CommonCRS.java |  9 ++--
 .../apache/sis/referencing/IdentifiedObjects.java  |  6 +--
 .../sis/referencing/crs/ExplicitParameters.java    | 11 ++---
 .../apache/sis/referencing/crs/package-info.java   |  2 +-
 .../org/apache/sis/referencing/cs/AbstractCS.java  | 11 +++--
 .../sis/referencing/cs/CoordinateSystems.java      |  5 +-
 .../sis/referencing/cs/DirectionAlongMeridian.java |  7 +--
 .../referencing/datum/DefaultGeodeticDatum.java    | 23 +++++----
 .../factory/AuthorityFactoryIdentifier.java        |  7 ++-
 .../factory/CommonAuthorityFactory.java            |  5 +-
 .../factory/ConcurrentAuthorityFactory.java        | 14 ++----
 .../factory/GeodeticAuthorityFactory.java          |  9 +++-
 .../referencing/factory/GeodeticObjectFactory.java |  9 ++--
 .../factory/IdentifiedObjectFinder.java            |  8 ++--
 .../referencing/factory/IdentifiedObjectSet.java   |  8 ++--
 .../factory/MultiAuthoritiesFactory.java           |  4 +-
 .../factory/sql/CloseableReference.java            |  7 +--
 .../referencing/factory/sql/EPSGCodeFinder.java    |  8 ++--
 .../referencing/factory/sql/EPSGDataAccess.java    | 19 ++++----
 .../sis/referencing/factory/sql/EPSGFactory.java   |  3 +-
 .../factory/sql/InstallationScriptProvider.java    |  6 +--
 .../sis/referencing/factory/sql/package-info.java  |  9 ++--
 .../operation/AbstractCoordinateOperation.java     | 12 +++--
 .../operation/CoordinateOperationRegistry.java     | 15 +++---
 .../operation/projection/NormalizedProjection.java |  8 ++--
 .../operation/transform/AbstractMathTransform.java |  9 +++-
 .../operation/transform/ConcatenatedTransform.java |  8 +---
 .../operation/transform/ContextualParameters.java  |  5 +-
 .../transform/DefaultMathTransformFactory.java     | 11 ++---
 .../operation/transform/WraparoundTransform.java   |  7 +--
 .../factory/ConcurrentAuthorityFactoryTest.java    |  6 +--
 .../sis/referencing/factory/TestFactorySource.java |  8 ++--
 .../apache/sis/internal/system/DataDirectory.java  |  7 +--
 .../sis/internal/system/DefaultFactories.java      |  5 +-
 .../sis/internal/system/DelayedExecutor.java       |  6 +--
 .../org/apache/sis/internal/system/Loggers.java    |  9 +++-
 .../sis/internal/system/OptionalDependency.java    |  2 +-
 .../internal/system/ReferenceQueueConsumer.java    |  6 +--
 .../org/apache/sis/internal/system/Shutdown.java   |  6 +--
 .../org/apache/sis/internal/system/Supervisor.java |  5 +-
 .../apache/sis/internal/system/SystemListener.java |  8 +++-
 .../org/apache/sis/internal/system/Threads.java    |  6 +--
 .../apache/sis/internal/util/DefinitionURI.java    |  6 ++-
 .../java/org/apache/sis/measure/AbstractUnit.java  |  9 +++-
 .../org/apache/sis/measure/QuantityFormat.java     |  5 +-
 .../main/java/org/apache/sis/measure/Scalar.java   |  5 +-
 .../java/org/apache/sis/measure/UnitFormat.java    |  5 +-
 .../java/org/apache/sis/measure/UnitRegistry.java  |  5 +-
 .../java/org/apache/sis/measure/UnitServices.java  |  4 +-
 .../src/main/java/org/apache/sis/setup/About.java  |  4 +-
 .../main/java/org/apache/sis/setup/OptionKey.java  |  2 +-
 .../java/org/apache/sis/setup/package-info.java    |  2 +-
 .../src/main/java/org/apache/sis/util/Locales.java |  5 +-
 .../java/org/apache/sis/util/logging/Logging.java  | 55 +++++++++++++++-------
 .../sis/util/resources/IndexedResourceBundle.java  | 16 ++++---
 .../apache/sis/util/resources/package-info.java    |  2 +-
 .../sis/storage/landsat/LandsatStoreProvider.java  | 18 ++++++-
 .../sis/storage/geotiff/GeoTiffStoreProvider.java  | 18 ++++++-
 .../org/apache/sis/internal/netcdf/Decoder.java    | 16 ++++---
 .../apache/sis/internal/netcdf/package-info.java   |  2 +-
 .../sis/storage/netcdf/NetcdfStoreProvider.java    | 14 ++++--
 .../apache/sis/storage/netcdf/package-info.java    |  2 +-
 .../apache/sis/storage/sql/SQLStoreProvider.java   | 18 ++++++-
 .../internal/storage/DocumentedStoreProvider.java  |  5 +-
 .../sis/internal/storage/csv/StoreProvider.java    | 20 +++++++-
 .../storage/esri/AsciiGridStoreProvider.java       | 18 ++++++-
 .../storage/esri/RawRasterStoreProvider.java       | 18 ++++++-
 .../sis/internal/storage/esri/package-info.java    |  2 +-
 .../sis/internal/storage/folder/StoreProvider.java | 18 ++++++-
 .../sis/internal/storage/folder/package-info.java  |  2 +-
 .../storage/image/WorldFileStoreProvider.java      | 18 ++++++-
 .../internal/storage/io/FileCacheByteChannel.java  |  5 +-
 .../apache/sis/internal/storage/package-info.java  |  2 +-
 .../sis/internal/storage/wkt/FirstKeywordPeek.java |  1 +
 .../sis/internal/storage/wkt/StoreProvider.java    | 18 ++++++-
 .../sis/internal/storage/wkt/package-info.java     |  2 +-
 .../sis/internal/storage/xml/StoreProvider.java    | 16 +++++++
 .../org/apache/sis/storage/DataStoreProvider.java  | 18 +------
 .../aggregate/ConcatenatedGridCoverage.java        |  9 ++--
 .../apache/sis/storage/aggregate/package-info.java |  2 +-
 .../apache/sis/storage/event/StoreListeners.java   |  5 +-
 .../sis/internal/storage/gpx/StoreProvider.java    | 16 +++++++
 169 files changed, 812 insertions(+), 604 deletions(-)

diff --git a/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java b/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java
index bd022690cd..dca273fca9 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java
+++ b/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java
@@ -60,7 +60,7 @@ import org.apache.sis.internal.util.X364;
  * See {@link org.apache.sis.console} package javadoc for more information.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.4
  * @since   0.3
  */
 final class AboutCommand extends CommandRunner {
@@ -145,7 +145,7 @@ final class AboutCommand extends CommandRunner {
                 final LogRecord record = Messages.getResources(locale).getLogRecord(Level.INFO,
                         Messages.Keys.ConfigurationOf_3, address, new Date(), delay);
                 record.setLoggerName(Loggers.APPLICATION);
-                Logging.log(Command.class, "main", record);
+                Logging.completeAndLog(null, Command.class, "main", record);
                 /*
                  * Replace the root node label from "Local configuration" to "Remote configuration"
                  * before to get the string representation of the configuration as a tree-table.
diff --git a/application/sis-console/src/main/java/org/apache/sis/console/package-info.java b/application/sis-console/src/main/java/org/apache/sis/console/package-info.java
index d3e6fc77ac..042447b74a 100644
--- a/application/sis-console/src/main/java/org/apache/sis/console/package-info.java
+++ b/application/sis-console/src/main/java/org/apache/sis/console/package-info.java
@@ -47,7 +47,7 @@
  * and Management Using JMX Technology</a> page.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.console;
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java
index a8a23068ea..7d4a3757e5 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java
@@ -75,14 +75,13 @@ import org.apache.sis.internal.gui.BackgroundThreads;
 import org.apache.sis.internal.gui.ExceptionReporter;
 import org.apache.sis.internal.gui.GUIUtilities;
 import org.apache.sis.internal.gui.LogHandler;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.measure.Units;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Debug;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -91,7 +90,7 @@ import static java.util.logging.Logger.getLogger;
  * instance (given by {@link #coverageProperty}) will change automatically according the zoom level.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see CoverageExplorer
  *
@@ -1148,7 +1147,7 @@ public class CoverageCanvas extends MapCanvasAWT {
      * Invoked when an exception occurred. The declared source method should be a public or protected method.
      */
     static void unexpectedException(final String method, final Exception e) {
-        Logging.unexpectedException(getLogger(Modules.APPLICATION), CoverageCanvas.class, method, e);
+        Logging.unexpectedException(LOGGER, CoverageCanvas.class, method, e);
     }
 
     /**
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridSliceSelector.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridSliceSelector.java
index d176a04712..51f4a0e08d 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridSliceSelector.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridSliceSelector.java
@@ -21,7 +21,6 @@ import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.text.ParseException;
 import java.util.Locale;
-import java.util.logging.Logger;
 import javafx.scene.Node;
 import javafx.scene.layout.Region;
 import javafx.scene.layout.GridPane;
@@ -52,7 +51,6 @@ import org.apache.sis.referencing.operation.transform.TransformSeparator;
 import org.apache.sis.referencing.crs.DefaultTemporalCRS;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridExtent;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.math.DecimalFunctions;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.gui.Widget;
@@ -64,6 +62,8 @@ import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Vocabulary;
 
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
+
 
 /**
  * A control for selecting a two-dimensional slice in a grid extent having more than 2 dimensions.
@@ -71,7 +71,7 @@ import org.apache.sis.util.resources.Vocabulary;
  * a slider for selecting a slice on the time axis.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.3
  */
 public class GridSliceSelector extends Widget {
@@ -387,7 +387,7 @@ public class GridSliceSelector extends Widget {
                     }
                 }
             } catch (FactoryException | ClassCastException e) {
-                Logging.ignorableException(Logger.getLogger(Modules.APPLICATION), GridSliceSelector.class,
+                Logging.ignorableException(LOGGER, GridSliceSelector.class,
                         "setGridGeometry", e);              // "gridGeometry.set(…)" is the public API.
             }
             /*
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureTable.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureTable.java
index dba7cec6eb..b8ffecac1e 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureTable.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureTable.java
@@ -44,14 +44,13 @@ import org.opengis.feature.FeatureAssociationRole;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.internal.util.Strings;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.storage.FeatureSet;
 import org.apache.sis.internal.feature.AttributeConvention;
 import org.apache.sis.internal.gui.IdentityValueFactory;
 import org.apache.sis.internal.gui.ExceptionReporter;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -80,7 +79,7 @@ import static java.util.logging.Logger.getLogger;
  * @author  Johann Sorel (Geomatys)
  * @author  Smaniotto Enzo (GSoC)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 @DefaultProperty("features")
@@ -483,13 +482,13 @@ public class FeatureTable extends TableView<Feature> {
      * public API (if possible) invoking the method where the exception is caught.
      */
     static void unexpectedException(final String method, final Throwable exception) {
-        Logging.unexpectedException(getLogger(Modules.APPLICATION), FeatureTable.class, method, exception);
+        Logging.unexpectedException(LOGGER, FeatureTable.class, method, exception);
     }
 
     /**
      * Reports an exception that we choose to ignore.
      */
     static void recoverableException(final String method, final Exception exception) {
-        Logging.recoverableException(getLogger(Modules.APPLICATION), FeatureTable.class, method, exception);
+        Logging.recoverableException(LOGGER, FeatureTable.class, method, exception);
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java
index 078f9e246e..1135c37d28 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java
@@ -45,11 +45,10 @@ import org.apache.sis.internal.gui.DataStoreOpener;
 import org.apache.sis.internal.gui.BackgroundThreads;
 import org.apache.sis.internal.gui.ExceptionReporter;
 import org.apache.sis.internal.gui.Resources;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.storage.DataStoreProvider;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -72,7 +71,7 @@ import static java.util.logging.Logger.getLogger;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 public class ResourceTree extends TreeView<Resource> {
@@ -467,13 +466,13 @@ public class ResourceTree extends TreeView<Resource> {
      * Reports an ignorable exception in the given method.
      */
     private static void recoverableException(final String method, final Exception e) {
-        Logging.recoverableException(getLogger(Modules.APPLICATION), ResourceTree.class, method, e);
+        Logging.recoverableException(LOGGER, ResourceTree.class, method, e);
     }
 
     /**
      * Reports an unexpected but non-fatal exception in the given method.
      */
     static void unexpectedException(final String method, final Exception e) {
-        Logging.unexpectedException(getLogger(Modules.APPLICATION), ResourceTree.class, method, e);
+        Logging.unexpectedException(LOGGER, ResourceTree.class, method, e);
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/WindowHandler.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/WindowHandler.java
index 263e128bcf..de1a57e3e5 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/WindowHandler.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/WindowHandler.java
@@ -18,7 +18,6 @@ package org.apache.sis.gui.dataset;
 
 import java.util.Locale;
 import java.util.Optional;
-import java.util.logging.Logger;
 import javafx.application.Platform;
 import javafx.stage.Stage;
 import javafx.stage.Window;
@@ -41,11 +40,12 @@ import org.apache.sis.internal.gui.DataStoreOpener;
 import org.apache.sis.internal.gui.GUIUtilities;
 import org.apache.sis.internal.gui.PrivateAccess;
 import org.apache.sis.internal.gui.Resources;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
+
 
 /**
  * A separated window for visualizing a resource managed by {@link ResourceExplorer}.
@@ -54,7 +54,7 @@ import org.apache.sis.util.resources.Errors;
  * It may also be a tile in a mosaic of windows.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.3
  */
 public abstract class WindowHandler {
@@ -113,7 +113,7 @@ public abstract class WindowHandler {
             text = DataStoreOpener.findLabel(getResource(), manager.locale, true);
         } catch (DataStoreException | RuntimeException e) {
             text = Vocabulary.getResources(manager.locale).getString(Vocabulary.Keys.Unknown);
-            Logging.recoverableException(Logger.getLogger(Modules.APPLICATION), WindowHandler.class, "<init>", e);
+            Logging.recoverableException(LOGGER, WindowHandler.class, "<init>", e);
         }
         title.set(text);
         manager.modifiableWindowList.add(this);
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/GestureFollower.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/GestureFollower.java
index 060b3936da..275a84f0d0 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/GestureFollower.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/GestureFollower.java
@@ -20,7 +20,6 @@ import java.awt.geom.Point2D;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.NoninvertibleTransformException;
 import java.util.Optional;
-import java.util.logging.Logger;
 import javafx.scene.layout.Pane;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Path;
@@ -39,9 +38,10 @@ import org.opengis.referencing.operation.MathTransform2D;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.portrayal.TransformChangeEvent;
 import org.apache.sis.portrayal.CanvasFollower;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.logging.Logging;
 
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
+
 
 /**
  * A listener of mouse or keyboard events in a source canvas which can be reproduced in a target canvas.
@@ -58,7 +58,7 @@ import org.apache.sis.util.logging.Logging;
  * All events should be processed in the JavaFX thread.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.3
  */
 public class GestureFollower extends CanvasFollower implements EventHandler<MouseEvent> {
@@ -230,7 +230,7 @@ public class GestureFollower extends CanvasFollower implements EventHandler<Mous
         } catch (TransformException e) {
             cursorSourceValid = false;
             cursor.setVisible(false);
-            Logging.recoverableException(Logger.getLogger(Modules.APPLICATION), GestureFollower.class, "handle", e);
+            Logging.recoverableException(LOGGER, GestureFollower.class, "handle", e);
         }
     }
 
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/MapCanvas.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/MapCanvas.java
index 22e8e4296b..5f5b946dd1 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/MapCanvas.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/MapCanvas.java
@@ -75,7 +75,6 @@ import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.internal.util.Numerics;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.DelayedExecutor;
 import org.apache.sis.internal.system.DelayedRunnable;
 import org.apache.sis.internal.gui.BackgroundThreads;
@@ -90,7 +89,7 @@ import org.apache.sis.portrayal.RenderException;
 import org.apache.sis.portrayal.TransformChangeEvent;
 import org.apache.sis.referencing.IdentifiedObjects;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 import static org.apache.sis.internal.util.StandardDateFormat.NANOS_PER_MILLISECOND;
 
 
@@ -130,7 +129,7 @@ import static org.apache.sis.internal.util.StandardDateFormat.NANOS_PER_MILLISEC
  * </ol>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 public abstract class MapCanvas extends PlanarCanvas {
@@ -1515,7 +1514,7 @@ public abstract class MapCanvas extends PlanarCanvas {
      * Invoked when an unexpected exception occurred but it is okay to continue despite it.
      */
     private static void unexpectedException(final String method, final Exception e) {
-        Logging.unexpectedException(getLogger(Modules.APPLICATION), MapCanvas.class, method, e);
+        Logging.unexpectedException(LOGGER, MapCanvas.class, method, e);
     }
 
     /**
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/OperationFinder.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/OperationFinder.java
index 7bd4b83007..8d641a0ec4 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/OperationFinder.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/OperationFinder.java
@@ -33,9 +33,8 @@ import org.apache.sis.gui.coverage.CoverageCanvas;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Modules;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -45,7 +44,7 @@ import static java.util.logging.Logger.getLogger;
  * done in a background thread.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 abstract class OperationFinder extends Task<MathTransform> {
@@ -130,7 +129,7 @@ abstract class OperationFinder extends Task<MathTransform> {
             bbox.setBounds(areaOfInterest);
         } catch (TransformException e) {
             bbox = null;
-            Logging.recoverableException(getLogger(Modules.APPLICATION), getCallerClass(), getCallerMethod(), e);
+            Logging.recoverableException(LOGGER, getCallerClass(), getCallerMethod(), e);
         }
         MathTransform before = null;
         MathTransform after  = null;
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
index 1c653292dd..27c3df7629 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
@@ -20,7 +20,6 @@ import java.util.Arrays;
 import java.util.Locale;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.logging.Logger;
 import java.util.function.Predicate;
 import java.awt.image.RenderedImage;
 import java.beans.PropertyChangeEvent;
@@ -96,11 +95,12 @@ import org.apache.sis.internal.gui.ExceptionReporter;
 import org.apache.sis.internal.gui.GUIUtilities;
 import org.apache.sis.internal.gui.Resources;
 import org.apache.sis.internal.gui.Styles;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.gazetteer.ReferencingByIdentifiers;
 
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
+
 
 /**
  * A status bar showing geographic or projected coordinates under mouse cursor.
@@ -1679,6 +1679,6 @@ public class StatusBar extends Widget implements EventHandler<MouseEvent> {
      * Logs an error considered too minor for reporting on the status bar.
      */
     private static void recoverableException(final String caller, final Exception e) {
-        Logging.recoverableException(Logger.getLogger(Modules.APPLICATION), StatusBar.class, caller, e);
+        Logging.recoverableException(LOGGER, StatusBar.class, caller, e);
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesFormatter.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesFormatter.java
index 5f21fe3598..192856d836 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesFormatter.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesFormatter.java
@@ -36,7 +36,6 @@ import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.GridCoverage;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.coverage.Category;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.math.DecimalFunctions;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.measure.NumberRange;
@@ -44,7 +43,7 @@ import org.apache.sis.measure.UnitFormat;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 // Branch-dependent imports
 import org.opengis.coverage.CannotEvaluateException;
@@ -60,7 +59,7 @@ import org.opengis.coverage.CannotEvaluateException;
  * from a background thread.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 final class ValuesFormatter extends ValuesUnderCursor.Formatter {
@@ -515,7 +514,7 @@ final class ValuesFormatter extends ValuesUnderCursor.Formatter {
         final String message = e.getMessage();
         if (!message.equals(lastErrorMessage)) {
             lastErrorMessage = message;
-            Logging.recoverableException(getLogger(Modules.APPLICATION), ValuesUnderCursor.class, method, e);
+            Logging.recoverableException(LOGGER, ValuesUnderCursor.class, method, e);
         }
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
index a1d9737c66..d3127c755f 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
@@ -46,7 +46,6 @@ import javafx.scene.input.ClipboardContent;
 import org.opengis.util.InternationalString;
 import org.opengis.referencing.IdentifiedObject;
 import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.gui.Resources;
 import org.apache.sis.internal.gui.PropertyView;
 import org.apache.sis.internal.gui.PropertyValueFormatter;
@@ -56,7 +55,7 @@ import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -83,7 +82,7 @@ import static java.util.logging.Logger.getLogger;
  *
  * @author  Siddhesh Rane (GSoC)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.1
  */
 @DefaultProperty("content")
@@ -383,7 +382,7 @@ check:      if (data != null) {
                 flush();
                 value = buffer.toString();
             } catch (IOException e) {               // Should never happen because we append in a StringBuilder.
-                Logging.unexpectedException(getLogger(Modules.APPLICATION), Formatter.class, "call", e);
+                Logging.unexpectedException(LOGGER, Formatter.class, "call", e);
                 // Leave `value` as-is. It will be formatted using `Object.toString()`.
             }
             return new ReadOnlyObjectWrapper<>(value);
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java
index 135ca68667..3e4d1644cb 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java
@@ -23,7 +23,7 @@
  * @author  Smaniotto Enzo (GSoC)
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 package org.apache.sis.gui.metadata;
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java
index b876d4b4c8..72a3d5f8e6 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java
@@ -43,10 +43,9 @@ import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.internal.util.StandardDateFormat;
 import org.apache.sis.internal.gui.BackgroundThreads;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Strings;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -59,7 +58,7 @@ import static java.util.logging.Logger.getLogger;
  *       (see {@link #type} field).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 final class AuthorityCodes extends ObservableListBase<Code>
@@ -519,7 +518,7 @@ final class AuthorityCodes extends ObservableListBase<Code>
     private void errorOccurred(final Throwable e) {
         if (!hasError) {
             hasError = true;    // Not a big problem if we have race condition; error will just be logged twice.
-            Logging.unexpectedException(getLogger(Modules.APPLICATION), AuthorityCodes.class, "get", e);
+            Logging.unexpectedException(LOGGER, AuthorityCodes.class, "get", e);
         }
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/PositionableProjection.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/PositionableProjection.java
index e94c3c0cb1..c059ddd01f 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/PositionableProjection.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/PositionableProjection.java
@@ -28,7 +28,6 @@ import org.opengis.referencing.crs.ProjectedCRS;
 import org.apache.sis.internal.gui.Resources;
 import org.apache.sis.internal.referencing.GeodeticObjectBuilder;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.measure.AngleFormat;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Longitude;
@@ -40,7 +39,7 @@ import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -48,7 +47,7 @@ import static java.util.logging.Logger.getLogger;
  * The point of interest is typically determined by mouse location.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 @SuppressWarnings("serial")         // We do not guarantee serialization compatibility.
@@ -113,8 +112,7 @@ public abstract class PositionableProjection extends CodeList<PositionableProjec
             try {
                 cd = CommonCRS.forDatum(baseCRS);
             } catch (IllegalArgumentException e) {
-                Logging.recoverableException(getLogger(Modules.APPLICATION),
-                            PositionableProjection.class, "createProjectedCRS", e);
+                Logging.recoverableException(LOGGER, PositionableProjection.class, "createProjectedCRS", e);
                 cd = CommonCRS.WGS84;
             }
             return cd.universal(latitude, longitude);
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java
index 653121768a..319bac2f60 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java
@@ -62,11 +62,10 @@ import org.apache.sis.internal.gui.GUIUtilities;
 import org.apache.sis.internal.gui.NonNullObjectProperty;
 import org.apache.sis.internal.gui.OptionalDataDownloader;
 import org.apache.sis.internal.gui.RecentChoices;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -1078,7 +1077,7 @@ next:       for (int i=0; i<count; i++) {
      */
     protected void errorOccurred(final FactoryException e) {
         OptionalDataDownloader.reportIfInstalling(e);
-        Logging.recoverableException(getLogger(Modules.APPLICATION), RecentReferenceSystems.class, "getReferenceSystems", e);
+        Logging.recoverableException(LOGGER, RecentReferenceSystems.class, "getReferenceSystems", e);
     }
 
     /**
@@ -1089,6 +1088,6 @@ next:       for (int i=0; i<count; i++) {
      * @param  e  the error that occurred.
      */
     static void errorOccurred(final String caller, final Exception e) {
-        Logging.recoverableException(getLogger(Modules.APPLICATION), RecentReferenceSystems.class, caller, e);
+        Logging.recoverableException(LOGGER, RecentReferenceSystems.class, caller, e);
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/Utils.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/Utils.java
index cb16221e65..b3d41e35d6 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/Utils.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/Utils.java
@@ -27,20 +27,19 @@ import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.metadata.iso.extent.Extents;
 import org.apache.sis.geometry.ImmutableEnvelope;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.CRS;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
  * Utility methods shared by classes in this package only.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 final class Utils {
@@ -74,7 +73,7 @@ final class Utils {
             bbox.setBounds(areaOfInterest);
             return new ImmutableEnvelope(bbox);
         } catch (TransformException e) {
-            Logging.recoverableException(getLogger(Modules.APPLICATION), caller, method, e);
+            Logging.recoverableException(LOGGER, caller, method, e);
         }
         return null;
     }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/BackgroundThreads.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/BackgroundThreads.java
index 3bfa3e29cb..0b9e25e1b9 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/BackgroundThreads.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/BackgroundThreads.java
@@ -28,12 +28,11 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 import javafx.application.Platform;
 import org.apache.sis.gui.DataViewer;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.Threads;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.Exceptions;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -49,7 +48,7 @@ import static java.util.logging.Logger.getLogger;
  * Users should not rely on this implementation details.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 @SuppressWarnings("serial")                         // Not intended to be serialized.
@@ -198,6 +197,6 @@ public final class BackgroundThreads extends AtomicInteger implements ThreadFact
      * @param  e       the exception that interrupted the waiting process.
      */
     private static void interrupted(final String method, final InterruptedException e) {
-        Logging.unexpectedException(getLogger(Modules.APPLICATION), BackgroundThreads.class, method, e);
+        Logging.unexpectedException(LOGGER, BackgroundThreads.class, method, e);
     }
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java
index 17f71ad806..19a3e5e6cc 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java
@@ -37,13 +37,12 @@ import org.apache.sis.image.PlanarImage;
 import org.apache.sis.internal.map.coverage.RenderingWorkaround;
 import org.apache.sis.internal.coverage.j2d.ColorModelFactory;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.math.Statistics;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -60,7 +59,7 @@ import static java.util.logging.Logger.getLogger;
  * This policy may change in any future version.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.1
  */
 final class ImageConverter extends Task<Statistics[]> {
@@ -211,7 +210,7 @@ final class ImageConverter extends Task<Statistics[]> {
             return processor.visualize((RenderedImage) mask, MASK_TRANSPARENCY);
         } catch (IllegalArgumentException e) {
             // Ignore, we will not apply any mask. Declare PropertyView.setImage(…) as the public method.
-            Logging.recoverableException(getLogger(Loggers.APPLICATION), PropertyView.class, "setImage", e);
+            Logging.recoverableException(LOGGER, PropertyView.class, "setImage", e);
         }
         return null;
     }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/LogHandler.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/LogHandler.java
index 17dd5a95cc..8f2800ccce 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/LogHandler.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/LogHandler.java
@@ -34,6 +34,7 @@ import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.event.StoreListener;
 import org.apache.sis.storage.event.WarningEvent;
 import org.apache.sis.internal.system.Configuration;
+import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.CharSequences;
 
@@ -43,10 +44,15 @@ import org.apache.sis.util.CharSequences;
  * This class maintains both a global (system) list and a list of log records specific to each resource.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 public final class LogHandler extends Handler implements StoreListener<WarningEvent> {
+    /**
+     * The logger for the JavaFX application.
+     */
+    public static final Logger LOGGER = Logger.getLogger(Modules.APPLICATION);
+
     /**
      * Maximal number of log records stored by this class.
      */
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Styles.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Styles.java
index b320d6275e..ae5bbc848b 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Styles.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Styles.java
@@ -30,10 +30,9 @@ import javafx.scene.layout.GridPane;
 import javafx.scene.layout.Priority;
 import javafx.scene.layout.RowConstraints;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.Static;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.gui.LogHandler.LOGGER;
 
 
 /**
@@ -44,7 +43,7 @@ import static java.util.logging.Logger.getLogger;
  * <p>This class also opportunistically provides a few utility methods related to appearance.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 public final class Styles extends Static {
@@ -154,7 +153,7 @@ public final class Styles extends Static {
             error = e;
         }
         if (error != null) {
-            Logging.unexpectedException(getLogger(Modules.APPLICATION), caller, method, error);
+            Logging.unexpectedException(LOGGER, caller, method, error);
         }
         return image;
     }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/package-info.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/package-info.java
index 288032722a..ca9e3a4c52 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/package-info.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/package-info.java
@@ -25,7 +25,7 @@
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 package org.apache.sis.internal.gui;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java
index d805f6d09c..e5f653f6d5 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java
@@ -43,11 +43,8 @@ import org.apache.sis.measure.Units;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Numerics;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Finds a transform from grid cells in a source coverage to geospatial positions in the CRS of a target coverage.
@@ -77,7 +74,7 @@ import static java.util.logging.Logger.getLogger;
  *
  * @author  Alexis Manin (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.1
  */
 final class CoordinateOperationFinder implements Supplier<double[]> {
@@ -745,6 +742,6 @@ apply:          if (forwardChangeOfCRS == null) {
      * @param  e       the ignorable exception.
      */
     private static void recoverableException(final String caller, final Exception e) {
-        Logging.recoverableException(getLogger(Modules.RASTER), CoordinateOperationFinder.class, caller, e);
+        Logging.recoverableException(GridExtent.LOGGER, CoordinateOperationFinder.class, caller, e);
     }
 }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java
index c7bd133c7b..8b156a7a9e 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java
@@ -42,13 +42,10 @@ import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.transform.TransformSeparator;
 import org.apache.sis.referencing.CRS;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 // Branch-dependent imports
 import org.opengis.coverage.CannotEvaluateException;
 import org.opengis.coverage.PointOutsideCoverageException;
@@ -67,7 +64,7 @@ import org.opengis.coverage.PointOutsideCoverageException;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see GridCoverage#evaluator()
  *
@@ -653,6 +650,6 @@ class DefaultEvaluator implements GridCoverage.Evaluator {
      * @param  exception  the exception that occurred.
      */
     private static void recoverableException(final String caller, final TransformException exception) {
-        Logging.recoverableException(getLogger(Modules.RASTER), DefaultEvaluator.class, caller, exception);
+        Logging.recoverableException(GridExtent.LOGGER, DefaultEvaluator.class, caller, exception);
     }
 }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
index 7a0f1b2c9d..c279ebefa1 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
@@ -39,13 +39,10 @@ import org.apache.sis.image.Interpolation;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.collection.WeakHashSet;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.FinalFieldSetter;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.measure.NumberRange;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * A predefined set of operations on grid coverages as convenience methods.
@@ -54,7 +51,7 @@ import static java.util.logging.Logger.getLogger;
  * {@code GridCoverageProcessor} is safe for concurrent use in multi-threading environment.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see org.apache.sis.image.ImageProcessor
  *
@@ -510,7 +507,7 @@ public class GridCoverageProcessor implements Cloneable {
      * @param  ex      the ignorable exception.
      */
     static void recoverableException(final String caller, final Exception ex) {
-        Logging.recoverableException(getLogger(Modules.RASTER), GridCoverageProcessor.class, caller, ex);
+        Logging.recoverableException(GridExtent.LOGGER, GridCoverageProcessor.class, caller, ex);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
index c3ef4af11e..35c0f58f8c 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
@@ -22,6 +22,7 @@ import java.util.SortedMap;
 import java.util.Arrays;
 import java.util.Optional;
 import java.util.Locale;
+import java.util.logging.Logger;
 import java.io.Serializable;
 import java.io.IOException;
 import java.io.UncheckedIOException;
@@ -66,8 +67,6 @@ import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.internal.system.Modules;
 
-import static java.util.logging.Logger.getLogger;
-
 // Branch-dependent imports
 import org.opengis.coverage.grid.GridEnvelope;
 import org.opengis.coverage.grid.GridCoordinates;
@@ -101,6 +100,12 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
      */
     private static final long serialVersionUID = -4717353677844056017L;
 
+    /**
+     * The logger for operations on grid coverages. Declared in this {@code GridExtent}
+     * class because it is among the first ones in the chain of dependencies.
+     */
+    static final Logger LOGGER = Logger.getLogger(Modules.RASTER);
+
     /**
      * The dimension name types for given coordinate system axis directions.
      * This map contains only the "positive" axis directions.
@@ -1210,7 +1215,7 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
             }
         } catch (FactoryException e) {
             // "toEnvelope" is the closest public method that may invoke this method.
-            Logging.recoverableException(getLogger(Modules.RASTER), GridExtent.class, "toEnvelope", e);
+            Logging.recoverableException(LOGGER, GridExtent.class, "toEnvelope", e);
         }
     }
 
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
index 86ec1e0ad2..7ea425dd19 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
@@ -60,7 +60,6 @@ import org.apache.sis.internal.referencing.DirectPositionView;
 import org.apache.sis.internal.referencing.TemporalAccessor;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.internal.metadata.ReferencingServices;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.feature.Resources;
 import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.internal.util.Numerics;
@@ -84,7 +83,6 @@ import org.apache.sis.io.TableAppender;
 import org.apache.sis.xml.NilObject;
 import org.apache.sis.xml.NilReason;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.referencing.CRS.findOperation;
 
 
@@ -585,7 +583,7 @@ public class GridGeometry implements LenientComparable, Serializable {
      * @param  exception  the exception that occurred.
      */
     static void recoverableException(final String caller, final TransformException exception) {
-        Logging.recoverableException(getLogger(Modules.RASTER), GridGeometry.class, caller, exception);
+        Logging.recoverableException(GridExtent.LOGGER, GridGeometry.class, caller, exception);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java b/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java
index d8e1c54604..5b8b09389d 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java
@@ -19,11 +19,13 @@ package org.apache.sis.feature;
 import java.util.Map;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.logging.Logger;
 import java.io.Serializable;
 import org.opengis.util.NameFactory;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.Deprecable;
 import org.apache.sis.util.iso.Types;
@@ -38,7 +40,7 @@ import org.opengis.feature.IdentifiedType;
  * Identification and description information inherited by property types and feature types.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.4
  * @since   0.5
  */
 public class AbstractIdentifiedType implements IdentifiedType, Deprecable, Serializable {
@@ -47,6 +49,11 @@ public class AbstractIdentifiedType implements IdentifiedType, Deprecable, Seria
      */
     private static final long serialVersionUID = 277130188958446740L;
 
+    /**
+     * The logger used by feature implementations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Modules.FEATURE);
+
     /**
      * Key for the <code>{@value}</code> property to be given to the constructor.
      * This is used for setting the value to be returned by {@link #getName()}.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java b/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
index 6b55312d79..95eb82490c 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
@@ -47,12 +47,9 @@ import org.apache.sis.internal.util.Strings;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.feature.GeometryWrapper;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.math.MathFunctions;
 
-import static java.util.logging.Logger.getLogger;
-
 // Branch-dependent imports
 import org.opengis.feature.IdentifiedType;
 import org.opengis.feature.Property;
@@ -92,7 +89,7 @@ import org.opengis.feature.Operation;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.5
  */
 public class FeatureFormat extends TabularFormat<Object> {
@@ -586,7 +583,7 @@ public class FeatureFormat extends TabularFormat<Object> {
                                                 final int bits = Float.floatToRawIntBits(f);
                                                 if (bits != illegalNaN) {
                                                     illegalNaN = bits;
-                                                    Logging.recoverableException(getLogger(Modules.FEATURE), FeatureFormat.class, "format", e);
+                                                    Logging.recoverableException(AbstractIdentifiedType.LOGGER, FeatureFormat.class, "format", e);
                                                 }
                                             }
                                         }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java b/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java
index 7cccd4c0c5..5749ae8bfb 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java
@@ -93,7 +93,7 @@
  * @author  Travis L. Pinney
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   0.5
  */
 package org.apache.sis.feature;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/BandedSampleConverter.java b/core/sis-feature/src/main/java/org/apache/sis/image/BandedSampleConverter.java
index 8858a7061d..2c55e46362 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/BandedSampleConverter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/BandedSampleConverter.java
@@ -36,14 +36,13 @@ import org.apache.sis.internal.coverage.j2d.ImageLayout;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
 import org.apache.sis.internal.coverage.j2d.TileOpExecutor;
 import org.apache.sis.internal.coverage.j2d.WriteSupport;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.Disposable;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.math.DecimalFunctions;
 import org.apache.sis.measure.NumberRange;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.coverage.j2d.ImageUtilities.LOGGER;
 
 
 /**
@@ -66,7 +65,7 @@ import static java.util.logging.Logger.getLogger;
  * In such case, writing converted values will cause the corresponding source values to be updated too.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 class BandedSampleConverter extends ComputedImage {
@@ -217,7 +216,7 @@ class BandedSampleConverter extends ComputedImage {
             }
             return new Writable((WritableRenderedImage) source, sampleModel, colorModel, sourceRanges, converters, inverses);
         } catch (NoninvertibleTransformException e) {
-            Logging.recoverableException(getLogger(Modules.RASTER), ImageProcessor.class, "convert", e);
+            Logging.recoverableException(LOGGER, ImageProcessor.class, "convert", e);
         }
         return new BandedSampleConverter(source, sampleModel, colorModel, sourceRanges, converters);
     }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/ErrorAction.java b/core/sis-feature/src/main/java/org/apache/sis/image/ErrorAction.java
index 325aa52fca..9a88852481 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/ErrorAction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/ErrorAction.java
@@ -16,13 +16,12 @@
  */
 package org.apache.sis.image;
 
+import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.util.logging.SimpleFormatter;
 import java.awt.image.ImagingOpException;
 import org.apache.sis.internal.system.Modules;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Some common ways to handle exceptions occurring during tile calculation.
@@ -60,12 +59,12 @@ enum ErrorAction implements ErrorHandler {
             final LogRecord record = details.getDescription();
             if (record != null) {
                 if (this == LOG) {
-                    String logger = record.getLoggerName();
-                    if (logger == null) {
-                        logger = Modules.RASTER;
-                        record.setLoggerName(logger);
+                    String loggerName = record.getLoggerName();
+                    if (loggerName == null) {
+                        loggerName = Modules.RASTER;
+                        record.setLoggerName(loggerName);
                     }
-                    getLogger(logger).log(record);
+                    Logger.getLogger(loggerName).log(record);
                 } else {
                     final Throwable ex = record.getThrown();
                     if (ex instanceof Error) {
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/MaskImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/MaskImage.java
index 6642928040..95bf133fda 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/MaskImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/MaskImage.java
@@ -24,10 +24,9 @@ import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.internal.coverage.j2d.ColorModelFactory;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.coverage.j2d.ImageUtilities.LOGGER;
 
 
 /**
@@ -35,7 +34,7 @@ import static java.util.logging.Logger.getLogger;
  * This is the implementation of {@value ResampledImage#MASK_KEY} property value.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see ResampledImage#getProperty(String)
  * @see ResampledImage#MASK_KEY
@@ -61,7 +60,7 @@ final class MaskImage extends SourceAlignedImage {
             converter = ((Visualization.InterpConvert) image.interpolation).converter.inverse();
         } catch (NoninvertibleTransformException e) {
             // ResampledImage.getProperty("org.apache.sis.Mask") is the public caller of this constructor.
-            Logging.unexpectedException(getLogger(Modules.RASTER), ResampledImage.class, "getProperty", e);
+            Logging.unexpectedException(LOGGER, ResampledImage.class, "getProperty", e);
         }
         this.converter = converter;
     }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java
index b21609f5b0..f9cc28d46f 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java
@@ -39,7 +39,6 @@ import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
 import org.apache.sis.internal.coverage.j2d.FillValues;
 import org.apache.sis.internal.feature.Resources;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Disposable;
@@ -50,7 +49,7 @@ import org.apache.sis.geometry.Shapes2D;
 import org.apache.sis.measure.Quantities;
 import org.apache.sis.measure.Units;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.coverage.j2d.ImageUtilities.LOGGER;
 
 
 /**
@@ -72,7 +71,7 @@ import static java.util.logging.Logger.getLogger;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @see Interpolation
  * @see java.awt.image.AffineTransformOp
@@ -462,7 +461,7 @@ public class ResampledImage extends ComputedImage {
      * @param  error   the ignore which can be ignored.
      */
     private static void recoverableException(final String method, final Exception error) {
-        Logging.recoverableException(getLogger(Modules.RASTER), ResampledImage.class, method, error);
+        Logging.recoverableException(LOGGER, ResampledImage.class, method, error);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/package-info.java b/core/sis-feature/src/main/java/org/apache/sis/image/package-info.java
index 235cb32ae0..aa3380872f 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/package-info.java
@@ -42,7 +42,7 @@
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.0
  */
 package org.apache.sis.image;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java
index dc11a2f7e6..e79fd39687 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.coverage.j2d;
 
 import java.util.Arrays;
+import java.util.logging.Logger;
 import java.awt.Rectangle;
 import java.awt.color.ColorSpace;
 import java.awt.geom.AffineTransform;
@@ -44,7 +45,6 @@ import static java.lang.Math.floorDiv;
 import static java.lang.Math.addExact;
 import static java.lang.Math.toIntExact;
 import static java.lang.Math.multiplyFull;
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.internal.util.Numerics.COMPARISON_THRESHOLD;
 
 
@@ -54,7 +54,7 @@ import static org.apache.sis.internal.util.Numerics.COMPARISON_THRESHOLD;
  * (see {@code *Factory} classes for creating those objects).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.1
  */
 public final class ImageUtilities extends Static {
@@ -82,6 +82,11 @@ public final class ImageUtilities extends Static {
     @Configuration
     private static final int BUFFER_SIZE = 32 * DEFAULT_TILE_SIZE * Byte.SIZE;
 
+    /**
+     * The logger for operations on images and rasters.
+     */
+    public static final Logger LOGGER = Logger.getLogger(Modules.RASTER);
+
     /**
      * Do not allow instantiation of this class.
      */
@@ -373,7 +378,7 @@ public final class ImageUtilities extends Static {
                 }
                 if (!Arrays.equals(m1, m2)) {
                     // If this logging happen, we should revisit this method and improve it.
-                    getLogger(Modules.RASTER).warning("Band names may be in wrong order.");
+                    LOGGER.warning("Band names may be in wrong order.");
                 }
             }
         }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
index 042f496dd6..8fe1787c4a 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
@@ -20,6 +20,7 @@ import java.io.Serializable;
 import java.nio.ByteBuffer;
 import java.util.Optional;
 import java.util.Iterator;
+import java.util.logging.Logger;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
@@ -32,6 +33,7 @@ import org.apache.sis.geometry.WraparoundMethod;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.internal.referencing.AxisDirections;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.math.Vector;
 import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.util.resources.Errors;
@@ -55,7 +57,7 @@ import org.apache.sis.util.Classes;
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.7
  */
 public abstract class Geometries<G> implements Serializable {
@@ -64,6 +66,11 @@ public abstract class Geometries<G> implements Serializable {
      */
     private static final long serialVersionUID = 1856503921463395122L;
 
+    /**
+     * The logger for operations on geometries.
+     */
+    public static final Logger LOGGER = Logger.getLogger(Loggers.GEOMETRY);
+
     /**
      * The {@value} value, used by subclasses for identifying code that assume two- or three-dimensional objects.
      */
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryFactories.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryFactories.java
index b86e7be949..efc3d8b1f9 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryFactories.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryFactories.java
@@ -18,7 +18,6 @@ package org.apache.sis.internal.feature;
 
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.logging.Logging;
 
 
@@ -32,7 +31,7 @@ import org.apache.sis.util.logging.Logging;
  * <p>Note: we can bring this code back into {@link Geometries} if JEP 8209964 is implemented.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 final class GeometryFactories {
@@ -61,8 +60,7 @@ final class GeometryFactories {
         } catch (ReflectiveOperationException | LinkageError e) {
             LogRecord record = Resources.forLocale(null).getLogRecord(Level.CONFIG,
                     Resources.Keys.OptionalLibraryNotFound_2, name, e.toString());
-            record.setLoggerName(Loggers.GEOMETRY);
-            Logging.log(Geometries.class, "register", record);
+            Logging.completeAndLog(Geometries.LOGGER, Geometries.class, "register", record);
             return previous;
         }
         factory.fallback = previous;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
index 1167eda43c..392e087ef6 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
@@ -31,7 +31,6 @@ import org.apache.sis.util.logging.Logging;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.geometry.GeneralEnvelope;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.util.ArgumentChecks;
@@ -39,7 +38,7 @@ import org.locationtech.jts.geom.Envelope;
 import org.locationtech.jts.geom.Geometry;
 import org.locationtech.jts.geom.GeometryFactory;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.feature.Geometries.LOGGER;
 
 
 /**
@@ -52,7 +51,7 @@ import static java.util.logging.Logger.getLogger;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.0
  */
 public final class JTS extends Static {
@@ -217,7 +216,7 @@ public final class JTS extends Static {
                 bbox.setBounds(env);
             } catch (TransformException ex) {
                 bbox = null;
-                Logging.ignorableException(getLogger(Loggers.GEOMETRY), JTS.class, "transform", ex);
+                Logging.ignorableException(LOGGER, JTS.class, "transform", ex);
             }
         }
         return CRS.findOperation(sourceCRS, targetCRS, bbox);
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/package-info.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/package-info.java
index cbe4cf39b0..ece9d03d55 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/package-info.java
@@ -24,7 +24,7 @@
  * may change in incompatible ways in any future version without notice.
  *
  * @author  Johann Sorel (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.0
  */
 package org.apache.sis.internal.feature.jts;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/package-info.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/package-info.java
index c21aa8d9b1..99f61f597f 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/package-info.java
@@ -28,7 +28,7 @@
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.7
  */
 package org.apache.sis.internal.feature;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Node.java b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Node.java
index aa009f2c2c..0572263f99 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Node.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/Node.java
@@ -52,7 +52,7 @@ import org.opengis.feature.AttributeType;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 public abstract class Node implements Serializable {
@@ -61,6 +61,11 @@ public abstract class Node implements Serializable {
      */
     private static final long serialVersionUID = -749201100175374658L;
 
+    /**
+     * The logger for all operations relative to filters.
+     */
+    public static final Logger LOGGER = Logger.getLogger(Loggers.FILTER);
+
     /**
      * Scope of all names defined by SIS convention.
      *
@@ -281,12 +286,11 @@ public abstract class Node implements Serializable {
      * @see <a href="https://issues.apache.org/jira/browse/SIS-460">SIS-460</a>
      */
     protected final void warning(final Exception e, final boolean recoverable) {
-        final Logger logger = Logger.getLogger(Loggers.FILTER);
         final String method = (this instanceof Predicate) ? "test" : "apply";
         if (recoverable) {
-            Logging.recoverableException(logger, getClass(), method, e);
+            Logging.recoverableException(LOGGER, getClass(), method, e);
         } else {
-            Logging.unexpectedException(logger, getClass(), method, e);
+            Logging.unexpectedException(LOGGER, getClass(), method, e);
         }
     }
 }
diff --git a/core/sis-feature/src/test/java/org/apache/sis/internal/filter/sqlmm/RegistryTestCase.java b/core/sis-feature/src/test/java/org/apache/sis/internal/filter/sqlmm/RegistryTestCase.java
index ad4a6f1d3b..f3f685e4e3 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/internal/filter/sqlmm/RegistryTestCase.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/internal/filter/sqlmm/RegistryTestCase.java
@@ -27,13 +27,11 @@ import org.apache.sis.filter.DefaultFilterFactory;
 import org.apache.sis.filter.Optimization;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.geometry.WraparoundMethod;
+import org.apache.sis.internal.filter.Node;
 import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.feature.GeometryWrapper;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.math.Vector;
 
-import static java.util.logging.Logger.getLogger;
-
 // Test dependencies
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.test.LoggingWatcher;
@@ -59,7 +57,7 @@ import org.opengis.filter.ValueReference;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @param  <G> root class of geometry implementation.
  *
@@ -112,7 +110,7 @@ public abstract class RegistryTestCase<G> extends TestCase {
      * @see #assertNoUnexpectedLog()
      */
     @Rule
-    public final LoggingWatcher loggings = new LoggingWatcher(getLogger(Loggers.FILTER));
+    public final LoggingWatcher loggings = new LoggingWatcher(Node.LOGGER);
 
     /**
      * Creates a new test case.
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Dependencies.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Dependencies.java
index 047f5c75f0..605eb44098 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Dependencies.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Dependencies.java
@@ -28,12 +28,11 @@ import java.lang.annotation.RetentionPolicy;
  * must be in the same class than the annotated method. Transitive dependencies do not
  * need to be declared, but the dependency graph shall not contain cycle.
  *
- * <div class="note"><b>Example:</b>
+ * <h2>Example</h2>
  * {@code ResponsibleParty.individualName} is now deprecated and replaced by the first {@code Individual.name} value
  * found in {@code Responsibility.party} list. Consequently, the {@code DefaultResponsibleParty.getIndividualName()}
  * method is annotated with {@code @Dependencies("getParties")} where {@code getParties()} is a method inherited from
  * the parent class.
- * </div>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
index b490eb4380..14058d2d3e 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
@@ -26,7 +26,7 @@ import org.opengis.util.ControlledVocabulary;
 import org.opengis.metadata.citation.Citation;
 import org.apache.sis.internal.util.MetadataServices;
 import org.apache.sis.internal.metadata.sql.Initializer;
-import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.iso.Types;
@@ -34,14 +34,12 @@ import org.apache.sis.util.Exceptions;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.resources.Errors;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Implements the metadata services needed by the {@code "sis-utility"} module.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.6
  */
 public final class ServicesForUtility extends MetadataServices {
@@ -109,7 +107,7 @@ public final class ServicesForUtility extends MetadataServices {
                         server   = type.getMethod("getServerName", (Class[]) null).invoke(ds, (Object[]) null);
                     }
                 } catch (NoSuchMethodException e) {
-                    Logging.recoverableException(getLogger(Loggers.SYSTEM), MetadataServices.class, "getInformation", e);
+                    Logging.recoverableException(SystemListener.LOGGER, MetadataServices.class, "getInformation", e);
                 } catch (Exception e) {
                     // Leave the message unchanged if it contains at least 2 words.
                     String message = Exceptions.getLocalizedMessage(e, locale);
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
index eeea549d12..106a9b76ac 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
@@ -40,12 +40,11 @@ import org.apache.sis.setup.InstallationResources;
 import org.apache.sis.internal.system.Configuration;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.system.DataDirectory;
+import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.system.Shutdown;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.resources.Messages;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.internal.util.MetadataServices.EMBEDDED;
 
 
@@ -66,7 +65,7 @@ import static org.apache.sis.internal.util.MetadataServices.EMBEDDED;
  * All other methods are related to getting the {@code DataSource} instance, through JNDI or otherwise.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.7
  */
 public abstract class Initializer {
@@ -100,7 +99,7 @@ public abstract class Initializer {
     private static DataSource source;
 
     /**
-     * {@code true} if {@link #connected(DatabaseMetaData)} has been invoked at least once.
+     * {@code true} if {@link #connected(DatabaseMetaData, Class, String)} has been invoked at least once.
      * This is reset to {@code false} if the {@link #source} is changed.
      * We use this information for logging purpose.
      */
@@ -190,7 +189,7 @@ public abstract class Initializer {
                  * automatically by other kinds of JNDI events. Even if the listener is not unregistered,
                  * it will not hurt too badly: the DataSource would only be fetched more often than necessary.
                  */
-                Logging.recoverableException(getLogger(Loggers.SYSTEM), Listener.class, "objectChanged", e);
+                Logging.recoverableException(SystemListener.LOGGER, Listener.class, "objectChanged", e);
             }
             for (Initializer init : DefaultFactories.createServiceLoader(Initializer.class)) {
                 init.dataSourceChanged();
@@ -204,7 +203,7 @@ public abstract class Initializer {
          */
         @Override
         public void namingExceptionThrown(NamingExceptionEvent event) {
-            Logging.unexpectedException(getLogger(Loggers.SYSTEM),
+            Logging.unexpectedException(SystemListener.LOGGER,
                     Listener.class, "namingExceptionThrown", event.getException());
             objectChanged(null);
         }
@@ -291,8 +290,9 @@ public abstract class Initializer {
             } catch (NoInitialContextException | NameNotFoundException e) {
                 final LogRecord record = Messages.getResources(null).getLogRecord(
                         Level.CONFIG, Messages.Keys.JNDINotSpecified_1, JNDI);
-                record.setLoggerName(Loggers.SQL);
-                Logging.log(null, null, record);                // Let Logging.log(…) infers the public caller.
+
+                // The null arguments let `Logging` infers the public caller.
+                Logging.completeAndLog(LocalDataSource.LOGGER, null, null, record);
             }
             /*
              * At this point we determined that there is no JNDI context or no object binded to "jdbc/SpatialMetadata".
@@ -386,7 +386,7 @@ public abstract class Initializer {
                     }
                 }
             } catch (IOException e) {
-                Logging.unexpectedException(getLogger(Loggers.SQL), Initializer.class, "getDataSource", e);
+                Logging.unexpectedException(LocalDataSource.LOGGER, Initializer.class, "getDataSource", e);
                 // Continue - the system will fallback on the hard-coded subset of EPSG definitions.
             }
         }
@@ -399,12 +399,15 @@ public abstract class Initializer {
      * the record level is set to {@link Level#CONFIG}. On next calls, the level become {@link Level#FINE}.
      *
      * @param  metadata  the value of {@code DataSource.getConnection().getMetaData()} or equivalent.
-     * @return the record to log. Caller should set the source class name and source method name.
+     * @param  classe    the class to report as the source of the logging message.
+     * @param  method    the method to report as the source of the logging message.
      * @throws SQLException if an error occurred while fetching the database URL.
      *
      * @since 0.8
      */
-    public static LogRecord connected(final DatabaseMetaData metadata) throws SQLException {
+    public static void connected(final DatabaseMetaData metadata, final Class<?> classe, final String method)
+            throws SQLException
+    {
         final Level level;
         synchronized (Initializer.class) {
             level = connected ? Level.FINE : Level.CONFIG;
@@ -412,8 +415,7 @@ public abstract class Initializer {
         }
         final LogRecord record = Messages.getResources(null).getLogRecord(level,
                 Messages.Keys.ConnectedToGeospatialDatabase_1, SQLUtilities.getSimplifiedURL(metadata));
-        record.setLoggerName(Loggers.SYSTEM);
-        return record;
+        Logging.completeAndLog(SystemListener.LOGGER, classe, method, record);
     }
 
     /**
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/LocalDataSource.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/LocalDataSource.java
index 21efdbfec8..f464f003eb 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/LocalDataSource.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/LocalDataSource.java
@@ -37,8 +37,6 @@ import org.apache.sis.internal.system.DataDirectory;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.Strings;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * A data source for a database stored locally in the {@code $SIS_DATA} directory.
@@ -46,10 +44,15 @@ import static java.util.logging.Logger.getLogger;
  * It provides our {@linkplain #initialize() starting point} for initiating the system-wide connection.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.1
  */
 public final class LocalDataSource implements DataSource, Comparable<LocalDataSource> {
+    /**
+     * Where to log warnings.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.SQL);
+
     /**
      * The property name for the home of Derby databases.
      */
@@ -129,7 +132,7 @@ public final class LocalDataSource implements DataSource, Comparable<LocalDataSo
                     path = Paths.get(home).relativize(path);
                 } catch (IllegalArgumentException | SecurityException e) {
                     // The path cannot be relativized. This is okay.
-                    Logging.recoverableException(getLogger(Loggers.SQL), LocalDataSource.class, "<init>", e);
+                    Logging.recoverableException(LOGGER, LocalDataSource.class, "<init>", e);
                 }
                 path   = path.normalize();
                 dbFile = path.toString().replace(path.getFileSystem().getSeparator(), "/");
@@ -295,8 +298,7 @@ public final class LocalDataSource implements DataSource, Comparable<LocalDataSo
                 record.setLevel(Level.WARNING);
                 record.setThrown(e);
             }
-            record.setLoggerName(Loggers.SQL);
-            Logging.log(LocalDataSource.class, "shutdown", record);
+            Logging.completeAndLog(LOGGER, LocalDataSource.class, "shutdown", record);
         }
     }
 
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/package-info.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/package-info.java
index feaadef439..7830210233 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/package-info.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/package-info.java
@@ -73,7 +73,7 @@
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.7
  */
 package org.apache.sis.internal.metadata.sql;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/CitationConstant.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/CitationConstant.java
index cefe9d7342..67dfa6bb4f 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/CitationConstant.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/CitationConstant.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.simple;
 
 import java.util.Date;
 import java.util.Collection;
+import java.util.logging.Logger;
 import java.io.ObjectStreamException;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
@@ -36,8 +37,6 @@ import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Base class for the {@code public static final Citation} constants defined in some SIS classes.
@@ -46,7 +45,7 @@ import static java.util.logging.Logger.getLogger;
  * is available, then that simple primary key will be used as the citation title.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see IdentifierSpace
  * @see Citations
@@ -59,6 +58,11 @@ public class CitationConstant extends SimpleCitation {
      */
     private static final long serialVersionUID = -8429121584437634107L;
 
+    /**
+     * Where to log warnings when searching for an entry in the database.
+     */
+    private static final Logger LOGGER = Logger.getLogger(Loggers.SQL);
+
     /**
      * Class of {@code public static final Citation} constants which are also used as namespace for identifiers.
      * The most typical example is the "EPSG" authority which manage the codes identifying Coordinate Reference
@@ -182,7 +186,7 @@ public class CitationConstant extends SimpleCitation {
                          * the MetadataFallback class. So if we get this exception, a more serious error occurred.
                          * It is still not fatal however, since most of Citation content is informative.
                          */
-                        Logging.unexpectedException(getLogger(Loggers.SQL), CitationConstant.class, "delegate", e);
+                        Logging.unexpectedException(LOGGER, CitationConstant.class, "delegate", e);
                         c = new SimpleCitation(title);
                     }
                     delegate = c;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/package-info.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/package-info.java
index 937d4f75f7..1a375d906e 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/package-info.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/package-info.java
@@ -25,7 +25,7 @@
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.internal.simple;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
index 9399d96e1d..4c930fb5fb 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
@@ -29,15 +29,12 @@ import org.opengis.metadata.citation.Responsibility;
 import org.opengis.util.CodeList;
 import org.opengis.util.InternationalString;
 import org.apache.sis.internal.simple.SimpleIdentifier;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.measure.ValueRange;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.collection.CheckedContainer;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Description of a metadata property inferred from Java reflection.
@@ -48,16 +45,16 @@ import static java.util.logging.Logger.getLogger;
  * <p>This class implements also the {@link org.opengis.metadata.Identifier} and {@link CheckedContainer} interfaces.
  * Those features are not directly used by this class, but is published in the {@link MetadataStandard} javadoc.</p>
  *
- * <div class="note"><b>API note:</b>
+ * <h2>API note</h2>
  * The rational for implementing {@code CheckedContainer} is to consider each {@code ExtendedElementInformation}
  * instance as the set of all possible values for the property. If the information had a {@code contains(E)} method,
- * it would return {@code true} if the given value is valid for that property.</div>
+ * it would return {@code true} if the given value is valid for that property.
  *
  * <h2>Immutability and thread safety</h2>
  * This final class is immutable and thus thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.5
+ * @version 1.4
  *
  * @param <E>  the value type, either the method return type if not a collection,
  *             or the type of elements in the collection otherwise.
@@ -273,7 +270,7 @@ final class PropertyInformation<E> extends SimpleIdentifier           // Impleme
                      * to have an IllegalArgumentException while he didn't provided any argument.
                      * Returning null as a fallback is compliant with the method contract.
                      */
-                    Logging.unexpectedException(getLogger(Modules.METADATA), PropertyInformation.class, "getDomainValue", e);
+                    Logging.unexpectedException(StandardImplementation.LOGGER, PropertyInformation.class, "getDomainValue", e);
                     domain = null;
                 }
                 domainValue = domain;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
index 33244739d1..76d0f246aa 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
@@ -18,6 +18,7 @@ package org.apache.sis.metadata;
 
 import java.util.Map;
 import java.util.IdentityHashMap;
+import java.util.logging.Logger;
 import java.io.ObjectStreamException;
 import org.opengis.annotation.UML;
 import org.opengis.annotation.Classifier;
@@ -26,14 +27,13 @@ import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.internal.system.Modules;
 
-import static java.util.logging.Logger.getLogger;
 
 
 /**
  * Information about an Apache SIS metadata standard implementation.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 1.4
  * @since   0.3
  */
 final class StandardImplementation extends MetadataStandard {
@@ -42,6 +42,11 @@ final class StandardImplementation extends MetadataStandard {
      */
     private static final long serialVersionUID = 855786625369724248L;
 
+    /**
+     * The logger for metadata.
+     */
+    static final Logger LOGGER = Logger.getLogger(Modules.METADATA);
+
     /**
      * The root packages for metadata implementations, or {@code null} if none.
      * If non-null, then this string must ends with a trailing {@code "."}.
@@ -159,7 +164,7 @@ final class StandardImplementation extends MetadataStandard {
                         implementations.put(type, candidate);
                         return candidate.asSubclass(type);
                     } catch (ClassNotFoundException e) {
-                        Logging.recoverableException(getLogger(Modules.METADATA), MetadataStandard.class, "getImplementation", e);
+                        Logging.recoverableException(LOGGER, MetadataStandard.class, "getImplementation", e);
                     }
                     implementations.put(type, Void.TYPE);                       // Marker for "class not found".
                 }
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java
index c29768b5e3..24c207efe6 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java
@@ -119,7 +119,7 @@
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Adrian Custer (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.metadata;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
index 7c9551ddb6..dfa5e552a8 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
@@ -111,7 +111,7 @@ import org.apache.sis.util.iso.Types;
  *
  * @author  Touraïvane (IRD)
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.8
  */
 public class MetadataSource implements AutoCloseable {
@@ -345,8 +345,7 @@ public class MetadataSource implements AutoCloseable {
                 }
             }
             if (warning != null) {
-                warning.setLoggerName(Loggers.SYSTEM);
-                Logging.log(MetadataSource.class, "getProvided", warning);
+                Logging.completeAndLog(SystemListener.LOGGER, MetadataSource.class, "getProvided", warning);
             }
             if (!isTransient) {
                 instance = ms;
@@ -485,7 +484,7 @@ public class MetadataSource implements AutoCloseable {
         Connection c = connection;
         if (c == null) {
             connection = c = dataSource.getConnection();
-            Logging.log(MetadataSource.class, "lookup", Initializer.connected(c.getMetaData()));
+            Initializer.connected(c.getMetaData(), MetadataSource.class, "lookup");
             scheduleCloseTask();
         }
         return c;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/package-info.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/package-info.java
index babc86ff31..41878f197f 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/package-info.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/package-info.java
@@ -42,7 +42,7 @@
  *
  * @author  Touraïvane (IRD)
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @see org.apache.sis.referencing.factory.sql
  *
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/Types.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/Types.java
index aae61ea6bf..93694967b6 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/Types.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/Types.java
@@ -25,6 +25,7 @@ import java.util.ResourceBundle;
 import java.util.MissingResourceException;
 import java.util.IllformedLocaleException;
 import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.io.IOException;
 import java.io.InputStream;
@@ -46,11 +47,8 @@ import org.apache.sis.util.resources.Messages;
 import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.internal.util.CodeLists;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.system.Modules;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Static methods working on GeoAPI types and {@link CodeList} values.
@@ -99,7 +97,7 @@ import static java.util.logging.Logger.getLogger;
  *   }
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.3
  */
 public final class Types extends Static {
@@ -108,6 +106,11 @@ public final class Types extends Static {
      */
     private static final char SEPARATOR = '.';
 
+    /**
+     * The logger for metadata.
+     */
+    private static final Logger LOGGER = Logger.getLogger(Modules.METADATA);
+
     /**
      * The types for ISO 19115 UML identifiers. The keys are UML identifiers.
      * Values are either class names as {@link String} objects, or the {@link Class} instances.
@@ -351,7 +354,7 @@ public final class Types extends Static {
      * The {@link InternationalString} returned by the {@code Types.getDescription(…)} methods.
      *
      * @author  Martin Desruisseaux (Geomatys)
-     * @version 0.3
+     * @version 1.4
      * @since   0.3
      */
     private static class Description extends ResourceInternationalString {
@@ -394,7 +397,7 @@ public final class Types extends Static {
             try {
                 return super.toString(locale);
             } catch (MissingResourceException e) {
-                Logging.ignorableException(getLogger(Loggers.LOCALIZATION), ResourceInternationalString.class, "toString", e);
+                Logging.ignorableException(Messages.LOGGER, ResourceInternationalString.class, "toString", e);
                 return fallback();
             }
         }
@@ -783,8 +786,7 @@ public final class Types extends Static {
              * it is the public facade invoking this method.
              */
             final LogRecord record = Messages.getResources(null).getLogRecord(Level.WARNING, Messages.Keys.LocalesDiscarded);
-            record.setLoggerName(Modules.METADATA);
-            Logging.log(Types.class, "toInternationalString", record);
+            Logging.completeAndLog(LOGGER, Types.class, "toInternationalString", record);
         }
     }
 
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/LegacyCodes.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/LegacyCodes.java
index 6e8429ec93..cd7e8090e2 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/LegacyCodes.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/LegacyCodes.java
@@ -23,19 +23,17 @@ import java.util.Properties;
 import java.io.InputStream;
 import java.io.IOException;
 import org.opengis.metadata.Metadata;
-import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Mapping between some legacy codes (e.g. ISO 19115:2003) and newer codes (e.g. ISO 19115:2014).
  * Provided in a separated class for loading only when first needed.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.5
+ * @version 1.4
  * @since   0.5
  */
 final class LegacyCodes {
@@ -55,7 +53,7 @@ final class LegacyCodes {
         try (InputStream in = Metadata.class.getResourceAsStream("2003/charset-codes.properties")) {
             codes.load(in);
         } catch (IOException e) {
-            Logging.unexpectedException(getLogger(Loggers.XML), ValueConverter.class, "toCharset[Code]", e);
+            Logging.unexpectedException(Context.LOGGER, ValueConverter.class, "toCharset[Code]", e);
         }
         final int capacity = Containers.hashMapCapacity(codes.size());
         IANA_TO_LEGACY = new HashMap<>(capacity);
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/MarshallerPool.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/MarshallerPool.java
index a6867b5a2b..14ae58e2a0 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/MarshallerPool.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/MarshallerPool.java
@@ -26,18 +26,17 @@ import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.system.Configuration;
 import org.apache.sis.internal.system.DelayedExecutor;
 import org.apache.sis.internal.system.DelayedRunnable;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.jaxb.AdapterReplacement;
 import org.apache.sis.internal.jaxb.TypeRegistration;
+import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.CharSequences;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Creates and configures {@link Marshaller} or {@link Unmarshaller} objects for use with SIS.
@@ -61,7 +60,7 @@ import static java.util.logging.Logger.getLogger;
  * from multiple threads.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  *
  * @see XML
  * @see <a href="http://jaxb.java.net/guide/Performance_and_thread_safety.html">JAXB Performance and thread-safety</a>
@@ -74,6 +73,7 @@ public class MarshallerPool {
      * This is a very rough value: actual timeout will not be shorter,
      * but may be twice longer.
      */
+    @Configuration
     private static final long TIMEOUT = 15000000000L;           // 15 seconds.
 
     /**
@@ -210,7 +210,7 @@ public class MarshallerPool {
              * Not expected to happen because we are supposed
              * to reset the properties to their initial values.
              */
-            Logging.unexpectedException(getLogger(Loggers.XML), MarshallerPool.class, "recycle", exception);
+            Logging.unexpectedException(Context.LOGGER, MarshallerPool.class, "recycle", exception);
             return;
         }
         queue.push(marshaller);
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/XLink.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/XLink.java
index abfac9a314..78b59d2c64 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/XLink.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/XLink.java
@@ -29,9 +29,7 @@ import org.opengis.util.InternationalString;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.internal.system.Loggers;
-
-import static java.util.logging.Logger.getLogger;
+import org.apache.sis.internal.jaxb.Context;
 
 
 /**
@@ -74,7 +72,7 @@ import static java.util.logging.Logger.getLogger;
  *
  * @author  Guilhem Legal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 1.4
  *
  * @see <a href="http://www.w3.org/TR/xlink/">XML Linking Language</a>
  * @see <a href="http://schemas.opengis.net/xlink/1.0.0/xlinks.xsd">OGC schema</a>
@@ -864,7 +862,7 @@ public class XLink implements Serializable {
                 }
             } catch (NoSuchFieldException e) {
                 // Should never happen with Enums. But if it happen anyway, this is not a fatal error.
-                Logging.unexpectedException(getLogger(Loggers.XML), XLink.class, "toString", e);
+                Logging.unexpectedException(Context.LOGGER, XLink.class, "toString", e);
             }
             buffer.append(label).append("=\"").append(value).append('"');
         }
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
index b8091a7736..f23993485a 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
@@ -29,6 +29,7 @@ import java.awt.image.RenderedImage;
 import java.awt.geom.Rectangle2D;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.NoninvertibleTransformException;
+import java.util.logging.Logger;
 import org.opengis.util.FactoryException;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.metadata.extent.GeographicBoundingBox;
@@ -71,8 +72,6 @@ import org.apache.sis.util.Utilities;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.portrayal.PlanarCanvas;       // For javadoc.
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * The {@code RenderedImage} to draw in a {@link PlanarCanvas} together with transforms from pixel coordinates
@@ -104,10 +103,15 @@ import static java.util.logging.Logger.getLogger;
  * We wait to see if this class works well in the general case before doing special cases.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 public class RenderingData implements Cloneable {
+    /**
+     * The logger for portrayal.
+     */
+    private static final Logger LOGGER = Logger.getLogger(Modules.PORTRAYAL);
+
     /**
      * The {@value} value, for identifying code that assume two-dimensional objects.
      *
@@ -828,7 +832,7 @@ public class RenderingData implements Cloneable {
      * This method pretends that the warning come from {@link PlanarCanvas} class since it is the public API.
      */
     private static void recoverableException(final Exception e) {
-        Logging.recoverableException(getLogger(Modules.PORTRAYAL), PlanarCanvas.class, "render", e);
+        Logging.recoverableException(LOGGER, PlanarCanvas.class, "render", e);
     }
 
     /**
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/package-info.java b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/package-info.java
index 7d272fb857..eb0edf0dad 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/package-info.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/package-info.java
@@ -23,7 +23,7 @@
  * may change in incompatible ways in any future version without notice.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.2
  */
 package org.apache.sis.internal.map.coverage;
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java
index e9188ab0ca..1c0eb58c8e 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Canvas.java
@@ -120,13 +120,14 @@ import org.apache.sis.coverage.grid.GridExtent;
  * (typically) the center of the display area, but also to specify which slice to select in all dimensions
  * not shown by the display device.</p>
  *
- * <div class="note"><b>Example:</b> if some data have (<var>x</var>,<var>y</var>,<var>z</var>) dimensions and
+ * <h3>Example</h3>
+ * If some data have (<var>x</var>,<var>y</var>,<var>z</var>) dimensions and
  * other data have (<var>x</var>,<var>y</var>,<var>t</var>) dimensions, then the point of interest shall contain
  * coordinate values for at least all of the (<var>x</var>,<var>y</var>,<var>z</var>,<var>t</var>) dimensions
  * (i.e. it must be 4-dimensional, even if all data in this example are 3-dimensional). If the display device
  * is a two-dimensional screen showing map in the (<var>x</var>,<var>y</var>) dimensions (horizontal plane),
  * then the point of interest defines the <var>z</var> value (elevation or depth) and the <var>t</var> value
- * (date and time) of the slice to show.</div>
+ * (date and time) of the slice to show.
  *
  * <h2>Display device size</h2>
  * The geographic extent of data to be rendered is constrained by the zoom level and the display device size.
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/CanvasFollower.java b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/CanvasFollower.java
index d9e5bdd7a7..c568e78384 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/CanvasFollower.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/CanvasFollower.java
@@ -17,7 +17,6 @@
 package org.apache.sis.portrayal;
 
 import java.util.Optional;
-import java.util.logging.Logger;
 import java.awt.geom.Point2D;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.NoninvertibleTransformException;
@@ -36,7 +35,6 @@ import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.NullArgumentException;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.geometry.DirectPosition2D;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
 import org.apache.sis.referencing.operation.matrix.AffineTransforms2D;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
@@ -513,7 +511,7 @@ public class CanvasFollower implements PropertyChangeListener, Disposable {
      * @param  e  the exception that occurred.
      */
     private static void canNotCompute(final String caller, final Exception e) {
-        Logging.recoverableException(Logger.getLogger(Modules.PORTRAYAL), CanvasFollower.class, caller, e);
+        Logging.recoverableException(Observable.LOGGER, CanvasFollower.class, caller, e);
     }
 
     /**
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Observable.java b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Observable.java
index a66f9267db..2347f18d0e 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Observable.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/Observable.java
@@ -18,8 +18,10 @@ package org.apache.sis.portrayal;
 
 import java.util.Map;
 import java.util.HashMap;
+import java.util.logging.Logger;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ArraysExt;
 
@@ -36,10 +38,15 @@ import org.apache.sis.util.ArraysExt;
  *       like the index of the element modified in a list.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.1
  */
 abstract class Observable {
+    /**
+     * The logger for portrayal.
+     */
+    static final Logger LOGGER = Logger.getLogger(Modules.PORTRAYAL);
+
     /**
      * The registered listeners for each property, created when first needed.
      *
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/TransformChangeEvent.java b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/TransformChangeEvent.java
index ee6334e2b5..e71e2e5429 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/TransformChangeEvent.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/portrayal/TransformChangeEvent.java
@@ -17,7 +17,6 @@
 package org.apache.sis.portrayal;
 
 import java.util.Optional;
-import java.util.logging.Logger;
 import java.awt.geom.AffineTransform;
 import java.beans.PropertyChangeEvent;
 import org.opengis.geometry.DirectPosition;
@@ -27,7 +26,6 @@ import org.apache.sis.referencing.operation.matrix.AffineTransforms2D;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.coverage.grid.GridGeometry;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 
@@ -371,7 +369,7 @@ public class TransformChangeEvent extends PropertyChangeEvent {
     private void canNotCompute(final String method, final Exception e) {
         if (error == null) {
             error = e;
-            Logging.recoverableException(Logger.getLogger(Modules.PORTRAYAL), TransformChangeEvent.class, method, e);
+            Logging.recoverableException(Observable.LOGGER, TransformChangeEvent.class, method, e);
         } else {
             error.addSuppressed(e);
         }
diff --git a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
index f4d23e74dd..b1a4bcfcc1 100644
--- a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
+++ b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
@@ -72,7 +72,6 @@ import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.geometry.DirectPosition2D;
 import org.apache.sis.internal.referencing.Formulas;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.math.DecimalFunctions;
 import org.apache.sis.measure.Longitude;
@@ -80,8 +79,6 @@ import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Quantities;
 import org.apache.sis.measure.Units;
 
-import static java.util.logging.Logger.getLogger;
-
 // Branch-dependent imports
 import org.opengis.metadata.citation.Party;
 import org.opengis.referencing.gazetteer.Location;
@@ -142,7 +139,7 @@ import org.opengis.referencing.gazetteer.LocationType;
  * are not thread-safe; it is recommended to create a new {@code Coder} instance for each thread.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see CommonCRS#universal(double, double)
  * @see <a href="https://en.wikipedia.org/wiki/Military_Grid_Reference_System">Military Grid Reference System on Wikipedia</a>
@@ -303,8 +300,7 @@ public class MilitaryGridReferenceSystem extends ReferencingByIdentifiers {
             party = MetadataSource.getProvided().lookup(Party.class, "{org}NATO");
         } catch (MetadataStoreException e) {
             party = null;
-            Logging.unexpectedException(getLogger(Modules.REFERENCING_BY_IDENTIFIERS),
-                    MilitaryGridReferenceSystem.class, "<init>", e);
+            Logging.unexpectedException(LOGGER, MilitaryGridReferenceSystem.class, "<init>", e);
         }
         NamedIdentifier name = new NamedIdentifier(null, "NATO", Resources.formatInternational(Resources.Keys.MGRS), null, null);
         return properties(name, IDENTIFIER, party);
diff --git a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/ReferencingByIdentifiers.java b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/ReferencingByIdentifiers.java
index 2d9e276eeb..c03a5488c4 100644
--- a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/ReferencingByIdentifiers.java
+++ b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/ReferencingByIdentifiers.java
@@ -63,7 +63,7 @@ import org.opengis.referencing.gazetteer.ReferenceSystemUsingIdentifiers;
  * without synchronization.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see ModifiableLocationType
  * @see AbstractLocation
@@ -77,11 +77,17 @@ public abstract class ReferencingByIdentifiers extends AbstractReferenceSystem i
      */
     private static final long serialVersionUID = 5353942546043471933L;
 
+    /**
+     * The logger for coordinate operations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Modules.REFERENCING_BY_IDENTIFIERS);
+
     /**
      * Property used to characterize the spatial reference system.
      *
      * @see #getTheme()
      */
+    @SuppressWarnings("serial")         // Most SIS implementations are serializable.
     private final InternationalString theme;
 
     /**
@@ -89,6 +95,7 @@ public abstract class ReferencingByIdentifiers extends AbstractReferenceSystem i
      *
      * @see #getOverallOwner()
      */
+    @SuppressWarnings("serial")         // Most SIS implementations are serializable.
     private final Party overallOwner;
 
     /**
@@ -97,6 +104,7 @@ public abstract class ReferencingByIdentifiers extends AbstractReferenceSystem i
      *
      * @see #getLocationTypes()
      */
+    @SuppressWarnings("serial")         // Most SIS implementations are serializable.
     private final List<LocationType> locationTypes;
 
     /**
@@ -366,7 +374,7 @@ public abstract class ReferencingByIdentifiers extends AbstractReferenceSystem i
          * @param e       the transformation error.
          */
         static void recoverableException(final Class<?> caller, final String method, final Exception e) {
-            Logging.recoverableException(Logger.getLogger(Modules.REFERENCING_BY_IDENTIFIERS), caller, method, e);
+            Logging.recoverableException(LOGGER, caller, method, e);
         }
     }
 
diff --git a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java
index f71a5e1086..269ca39cf4 100644
--- a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java
+++ b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/package-info.java
@@ -31,7 +31,7 @@
  *
  * @author  Chris Mattmann (JPL)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.8
  */
 package org.apache.sis.referencing.gazetteer;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java
index 6412aa4037..556982b45f 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/CoordinateFormat.java
@@ -30,6 +30,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
+import java.util.logging.Logger;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.UncheckedIOException;
@@ -70,7 +71,6 @@ import org.apache.sis.measure.UnitFormat;
 import org.apache.sis.io.CompoundFormat;
 import org.apache.sis.referencing.CRS;
 
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -101,7 +101,7 @@ import static java.util.logging.Logger.getLogger;
  * transform the position} before to format it.</p>
  *
  * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see AngleFormat
  * @see org.apache.sis.measure.UnitFormat
@@ -110,6 +110,11 @@ import static java.util.logging.Logger.getLogger;
  * @since 0.8
  */
 public class CoordinateFormat extends CompoundFormat<DirectPosition> {
+    /**
+     * The logger for units of measurement.
+     */
+    private static final Logger LOGGER = Logger.getLogger(Loggers.MEASURE);
+
     /**
      * Serial number for cross-version compatibility.
      */
@@ -1819,13 +1824,14 @@ checkDirection: if (direction != null) {
     }
 
     /**
-     * Invoked when an expected error occurred but continuation is still possible.
+     * Invoked when an unexpected error occurred but continuation is still possible.
+     * This method is invoked in the context of units of measurement.
      *
      * @param  method  the public method to report as the source of the log record.
      * @param  error   the error that occurred.
      */
     private static void unexpectedException(final String method, final Exception error) {
-        Logging.unexpectedException(getLogger(Loggers.MEASURE), CoordinateFormat.class, method, error);
+        Logging.unexpectedException(LOGGER, CoordinateFormat.class, method, error);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
index 4736cef6b6..5c285b781a 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.ArrayList;
 import java.util.ConcurrentModificationException;
+import java.util.logging.Logger;
 import java.time.Instant;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
@@ -60,7 +61,6 @@ import org.apache.sis.util.Static;
 import org.apache.sis.measure.Range;
 import org.apache.sis.math.MathFunctions;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.util.StringBuilders.trimFractionalPart;
 
 
@@ -100,7 +100,7 @@ import static org.apache.sis.util.StringBuilders.trimFractionalPart;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see org.apache.sis.metadata.iso.extent.Extents
  * @see CRS
@@ -108,6 +108,11 @@ import static org.apache.sis.util.StringBuilders.trimFractionalPart;
  * @since 0.3
  */
 public final class Envelopes extends Static {
+    /**
+     * The logger for geometry operations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.GEOMETRY);
+
     /**
      * Fraction of the axis span to accept as close enough to an envelope boundary. This is used for coordinates
      * that are suppose to be on a boundary, for checking if it is really on the boundary side where it should be.
@@ -272,7 +277,7 @@ public final class Envelopes extends Static {
                      * Note: we may succeed to transform `source` and fail to transform `target` to geographic bounding box,
                      * but the opposite is unlikely because `source` should not have less dimensions than `target`.
                      */
-                    Logging.recoverableException(getLogger(Loggers.GEOMETRY), Envelopes.class, "findOperation", e);
+                    Logging.recoverableException(LOGGER, Envelopes.class, "findOperation", e);
                 }
                 return CRS.findOperation(sourceCRS, targetCRS, areaOfInterest);
             }
@@ -285,7 +290,7 @@ public final class Envelopes extends Static {
      * Those exceptions must be minor enough that they can be silently ignored in most cases.
      */
     static void recoverableException(final Class<? extends Static> caller, final TransformException exception) {
-        Logging.recoverableException(getLogger(Loggers.GEOMETRY), caller, "transform", exception);
+        Logging.recoverableException(LOGGER, caller, "transform", exception);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/WraparoundAdjustment.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/WraparoundAdjustment.java
index c18e2383b4..9b84c620fe 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/WraparoundAdjustment.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/WraparoundAdjustment.java
@@ -30,12 +30,10 @@ import org.apache.sis.math.MathFunctions;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.WraparoundAxesFinder;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
 
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -47,7 +45,7 @@ import static java.util.logging.Logger.getLogger;
  * <p>{@code WraparoundAdjustment} instances are not thread-safe.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.2
  */
 public class WraparoundAdjustment {
@@ -190,7 +188,7 @@ public class WraparoundAdjustment {
             geographicDomainKnown = true;                       // Shall be set even in case of failure.
             geographicDomain = ReferencingServices.getInstance().setBounds(domainOfValidity, null, null);
         } catch (TransformException e) {
-            Logging.ignorableException(getLogger(Loggers.COORDINATE_OPERATION), WraparoundAdjustment.class, "<init>", e);
+            Logging.ignorableException(Envelopes.LOGGER, WraparoundAdjustment.class, "<init>", e);
             // No more attempt will be done.
         }
         try {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java
index 25c060c688..369fc198fd 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java
@@ -87,7 +87,7 @@
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.geometry;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DefinitionVerifier.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DefinitionVerifier.java
index 497876a173..3ccfe8f853 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DefinitionVerifier.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/DefinitionVerifier.java
@@ -130,7 +130,7 @@ public final class DefinitionVerifier {
             final LogRecord record = verification.warning(true);
             if (record != null) {
                 record.setLoggerName(logger);
-                Logging.log(classe, method, record);
+                Logging.completeAndLog(null, classe, method, record);
             }
         }
     }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java
index 25847110b5..ee07ab6476 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java
@@ -32,9 +32,9 @@ import org.apache.sis.util.ArraysExt;
  * even if the string has the same value. It should be possible to change a keyword used in WKT formatting
  * without affecting GML for instance.</p>
  *
- * <div class="note"><b>Note:</b>
- * all constants in this class are static and final. The Java compiler should replace those constants
- * by their literal values at compile time, which avoid the loading of this class at run-time.</div>
+ * <h2>Implementation note</h2>
+ * All constants in this class are static and final. The Java compiler should replace those constants
+ * by their literal values at compile time, which avoid the loading of this class at run-time.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
index de549d7b32..df126fa6ad 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.referencing;
 
 import java.lang.reflect.Array;
 import java.util.function.Function;
+import java.util.logging.Logger;
 import javax.measure.Unit;
 import javax.measure.Quantity;
 import javax.measure.quantity.Angle;
@@ -46,6 +47,7 @@ import org.apache.sis.referencing.datum.DefaultPrimeMeridian;
 import org.apache.sis.referencing.datum.DefaultEllipsoid;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.internal.referencing.provider.Affine;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.parameter.DefaultParameterValue;
 import org.apache.sis.parameter.Parameterized;
 import org.apache.sis.io.wkt.ElementKind;
@@ -71,10 +73,15 @@ import org.apache.sis.math.Vector;
  * We need to be specific in order to select the right "aspect" of the given object.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   0.4
  */
 public final class WKTUtilities extends Static {
+    /**
+     * The logger for Well Known Text operations.
+     */
+    public static final Logger LOGGER = Logger.getLogger(Loggers.WKT);
+
     /**
      * Do not allow instantiation of this class.
      */
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
index be9b51e6a9..dd8002cada 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractProvider.java
@@ -19,6 +19,7 @@ package org.apache.sis.internal.referencing.provider;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Collection;
+import java.util.logging.Logger;
 import javax.xml.bind.annotation.XmlTransient;
 import org.opengis.util.GenericName;
 import org.opengis.metadata.Identifier;
@@ -43,14 +44,12 @@ import org.apache.sis.util.Workaround;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.internal.system.Loggers;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Base class for all providers defined in this package.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.6
  */
 @XmlTransient
@@ -60,6 +59,11 @@ public abstract class AbstractProvider extends DefaultOperationMethod implements
      */
     private static final long serialVersionUID = 1165868434518724597L;
 
+    /**
+     * The logger for coordinate operations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.COORDINATE_OPERATION);
+
     /**
      * The base interface of the {@code CoordinateOperation} instances that use this method.
      *
@@ -317,6 +321,6 @@ public abstract class AbstractProvider extends DefaultOperationMethod implements
      * @param  e       the error that occurred.
      */
     static void recoverableException(final Class<? extends AbstractProvider> caller, Exception e) {
-        Logging.recoverableException(getLogger(Loggers.COORDINATE_OPERATION), caller, "createMathTransform", e);
+        Logging.recoverableException(LOGGER, caller, "createMathTransform", e);
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java
index ca42083b37..8e046fdd86 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java
@@ -17,7 +17,6 @@
 package org.apache.sis.internal.referencing.provider;
 
 import java.util.logging.Level;
-import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.io.EOFException;
@@ -34,8 +33,6 @@ import java.nio.channels.Channels;
 import org.opengis.util.FactoryException;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Loggers;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.DataDirectory;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.referencing.factory.FactoryDataException;
@@ -179,7 +176,7 @@ abstract class DatumShiftGridLoader {
         try {
             return Files.newByteChannel(Paths.get(path));
         } catch (FileSystemNotFoundException e) {
-            Logging.ignorableException(Logger.getLogger(Modules.REFERENCING), DatumShiftGridLoader.class, "newByteChannel", e);
+            Logging.ignorableException(AbstractProvider.LOGGER, DatumShiftGridLoader.class, "newByteChannel", e);
         }
         return Channels.newChannel(path.toURL().openStream());
     }
@@ -200,11 +197,10 @@ abstract class DatumShiftGridLoader {
      *
      * @param  caller  the provider to logs as the source class.
      *                 the source method will be set to {@code "createMathTransform"}.
-     * @param record   the record to log.
+     * @param  record  the record to complete and log.
      */
     static void log(final Class<?> caller, final LogRecord record) {
-        record.setLoggerName(Loggers.COORDINATE_OPERATION);
-        Logging.log(caller, "createMathTransform", record);
+        Logging.completeAndLog(AbstractProvider.LOGGER, caller, "createMathTransform", record);
     }
 
     /**
@@ -220,8 +216,9 @@ abstract class DatumShiftGridLoader {
             if (directory != null && !datumDirectoryLogged.getAndSet(true)) {
                 final LogRecord record = Resources.forLocale(null).getLogRecord(
                         Level.INFO, Resources.Keys.DatumChangesDirectory_1, directory);
-                record.setLoggerName(Loggers.COORDINATE_OPERATION);
-                Logging.log(DatumShiftGridLoader.class, "readGrid", record);        // "readGrid" is actually defined by subclasses.
+
+                // "readGrid" is actually defined by subclasses.
+                Logging.completeAndLog(AbstractProvider.LOGGER, DatumShiftGridLoader.class, "readGrid", record);
             }
         }
         final boolean notFound = (cause instanceof NoSuchFileException);
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
index 2e7b64259e..b5160c1f1c 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
@@ -44,7 +44,6 @@ import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.opengis.util.FactoryException;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.referencing.NilReferencingObject;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.parameter.ParameterBuilder;
@@ -502,9 +501,10 @@ public class FranceGeocentricInterpolation extends GeodeticOperation {
                             if (!interp.matches("(?i)INTERPOLATION[^A-Z]+BILINEAIRE")) {
                                 final LogRecord record = Errors.getResources((Locale) null).getLogRecord(
                                         Level.WARNING, Errors.Keys.UnsupportedInterpolation_1, interp);
-                                record.setLoggerName(Loggers.COORDINATE_OPERATION);
-                                Logging.log(FranceGeocentricInterpolation.class, "createMathTransform", record);
+
                                 // We declare `createMathTransform(…)` method because it is closer to public API.
+                                Logging.completeAndLog(LOGGER, FranceGeocentricInterpolation.class,
+                                                       "createMathTransform", record);
                             }
                             break;
                         }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
index bc0a0e21b7..403df0047b 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
@@ -33,7 +33,6 @@ import org.opengis.referencing.operation.Transformation;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.referencing.WKTKeywords;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.measure.Units;
@@ -47,8 +46,6 @@ import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * The base class of operation methods performing a translation, rotation and/or scale in geocentric coordinates.
@@ -60,7 +57,7 @@ import static java.util.logging.Logger.getLogger;
  * "Geocentric translations" is an operation name defined by EPSG.</div>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.7
  */
 @XmlTransient
@@ -461,7 +458,7 @@ public abstract class GeocentricAffine extends GeodeticOperation {
                          * Should not occur, except sometimes on inverse transform of relatively complex datum shifts
                          * (more than just translation terms). We can fallback on formatting the full matrix.
                          */
-                        Logging.recoverableException(getLogger(Loggers.WKT), GeocentricAffine.class, "asDatumShift", e);
+                        Logging.recoverableException(WKTUtilities.LOGGER, GeocentricAffine.class, "asDatumShift", e);
                         continue;
                     }
                     final boolean isTranslation = parameters.isTranslation();
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
index d3cff9d3b7..fbe34851fd 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
@@ -55,10 +55,17 @@ import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
  *
  * @author  Rémi Eve (IRD)
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   0.6
  */
 abstract class AbstractParser implements Parser {
+    /**
+     * The logger for Well Known Text operations.
+     *
+     * @see #log(LogRecord)
+     */
+    private static final Logger LOGGER = Logger.getLogger(Loggers.WKT);
+
     /**
      * A mode for the {@link Element#pullElement(int, String...)} method meaning that only the first element
      * should be checked. If the name of the first element does not match one of the specified names, then
@@ -214,11 +221,10 @@ abstract class AbstractParser implements Parser {
      * or when the information is not worth to report as a warning.
      */
     final void log(final LogRecord record) {
-        Logger logger = Logger.getLogger(Loggers.WKT);
         record.setSourceClassName (getPublicFacade());
         record.setSourceMethodName(getFacadeMethod());
-        record.setLoggerName(logger.getName());
-        logger.log(record);
+        record.setLoggerName(Loggers.WKT);
+        LOGGER.log(record);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
index 4f1173bfeb..e71360147e 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
@@ -26,6 +26,7 @@ import java.util.TreeMap;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.util.function.Function;
 import java.io.IOException;
@@ -49,8 +50,8 @@ import org.apache.sis.io.CompoundFormat;
 import org.apache.sis.measure.UnitFormat;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.StandardDateFormat;
@@ -80,7 +81,7 @@ import org.apache.sis.referencing.ImmutableIdentifier;
  * After fragments have been added, any call to a parsing method will replace all occurrences (except in
  * quoted text) of tokens like {@code $foo} by the WKT fragment named "foo".
  *
- * <div class="note"><b>Example:</b>
+ * <h3>Example</h3>
  * In the example below, the {@code $WGS84} substring which appear in the argument given to the
  * {@code parseObject(…)} method will be expanded into the full {@code GeodeticCRS[“WGS84”, …]}
  * string before the parsing proceed.
@@ -97,7 +98,6 @@ import org.apache.sis.referencing.ImmutableIdentifier;
  *
  * Note that the parsing of WKT fragment does not always produce the same object.
  * In particular, the default linear and angular units depend on the context in which the WKT fragment appears.
- * </div>
  *
  * <h2>Limitations</h2>
  * <ul>
@@ -116,7 +116,7 @@ import org.apache.sis.referencing.ImmutableIdentifier;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Rémi Eve (IRD)
- * @version 1.1
+ * @version 1.4
  *
  * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
  * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy WKT 1</a>
@@ -124,6 +124,11 @@ import org.apache.sis.referencing.ImmutableIdentifier;
  * @since 0.4
  */
 public class WKTFormat extends CompoundFormat<Object> {
+    /**
+     * The logger for Well Known Text operations.
+     */
+    private static final Logger LOGGER = Logger.getLogger(Loggers.WKT);
+
     /**
      * For cross-version compatibility.
      */
@@ -1111,8 +1116,7 @@ public class WKTFormat extends CompoundFormat<Object> {
              * reference for long, so we do not need to copy the `AbstractParser.ignoredElements` map.
              */
             final LogRecord record = new LogRecord(Level.WARNING, warnings.toString());
-            record.setLoggerName(Loggers.WKT);
-            Logging.log(classe, method, record);
+            Logging.completeAndLog(LOGGER, classe, method, record);
         }
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java b/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
index f6efa95e34..edbd84b655 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
@@ -18,6 +18,7 @@ package org.apache.sis.parameter;
 
 import java.lang.reflect.Array;
 import java.util.Objects;
+import java.util.logging.Logger;
 import java.nio.file.Path;
 import java.io.Serializable;
 import java.io.File;
@@ -57,7 +58,6 @@ import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.UnconvertibleObjectException;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.util.Utilities.deepEquals;
 
@@ -118,7 +118,7 @@ import static org.apache.sis.util.Utilities.deepEquals;
  * for modifying the behavior of all getter and setter methods.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @param  <T>  the type of the value stored in this parameter.
  *
@@ -140,6 +140,11 @@ public class DefaultParameterValue<T> extends FormattableObject implements Param
      */
     private static final long serialVersionUID = -5837826787089486776L;
 
+    /**
+     * The logger for parameters.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.PARAMETER);
+
     /**
      * The definition of this parameter.
      *
@@ -601,8 +606,7 @@ public class DefaultParameterValue<T> extends FormattableObject implements Param
                      * Level.FINE (not WARNING) because this log duplicates the exception
                      * that `setValue(Object, Unit)` may throw (with a better message).
                      */
-                    Logging.recoverableException(getLogger(Loggers.COORDINATE_OPERATION),
-                            DefaultParameterValue.class, "setValue", e);
+                    Logging.recoverableException(LOGGER, DefaultParameterValue.class, "setValue", e);
                 } else {
                     /*
                      * If the given value is an array, verify if array elements need to be converted
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/parameter/Verifier.java b/core/sis-referencing/src/main/java/org/apache/sis/parameter/Verifier.java
index 904211486c..91948baf3d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/parameter/Verifier.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/parameter/Verifier.java
@@ -31,7 +31,6 @@ import org.opengis.parameter.InvalidParameterValueException;
 import org.apache.sis.internal.referencing.EPSGParameterDomain;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.system.Semaphores;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.measure.Range;
 import org.apache.sis.measure.Units;
@@ -47,7 +46,7 @@ import org.apache.sis.util.resources.Vocabulary;
  * In such case, the error message is given by {@link #message(Map, String, Object)}.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.4
  */
 final class Verifier {
@@ -224,9 +223,8 @@ final class Verifier {
                 if (!Semaphores.query(Semaphores.SUSPEND_PARAMETER_CHECK)) {
                     throw new InvalidParameterValueException(message, name, value);
                 } else {
-                    final LogRecord record = new LogRecord(Level.WARNING, message);
-                    record.setLoggerName(Loggers.COORDINATE_OPERATION);
-                    Logging.log(DefaultParameterValue.class, "setValue", record);
+                    Logging.completeAndLog(DefaultParameterValue.LOGGER, DefaultParameterValue.class,
+                                           "setValue", new LogRecord(Level.WARNING, message));
                 }
             }
         }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/parameter/package-info.java b/core/sis-referencing/src/main/java/org/apache/sis/parameter/package-info.java
index e8553014ff..7ca0d22945 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/parameter/package-info.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/parameter/package-info.java
@@ -85,7 +85,7 @@
  * if the given value is not assignable to the expected class or is not inside the value domain.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.4
  */
 @XmlSchema(elementFormDefault= XmlNsForm.QUALIFIED, namespace = Namespaces.GML, xmlns = {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
index b72bc7af9c..1d67cf0fb9 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
@@ -21,6 +21,7 @@ import java.util.ServiceLoader;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.sql.SQLTransientException;
+import java.util.logging.Logger;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.cs.CSAuthorityFactory;
@@ -46,10 +47,15 @@ import org.apache.sis.util.logging.Logging;
  * future SIS version (this may require more help from {@link ServiceLoader}).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.4
  * @since   0.7
  */
 final class AuthorityFactories<T extends AuthorityFactory> extends LazySet<T> {
+    /**
+     * The logger to use for reporting object creations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.CRS_FACTORY);
+
     /**
      * An array containing only the EPSG factory. Content of this array is initially null.
      * The EPSG factory will be created when first needed by {@link #initialValues()}.
@@ -196,8 +202,7 @@ final class AuthorityFactories<T extends AuthorityFactory> extends LazySet<T> {
         if (isWarning && !(e instanceof UnavailableFactoryException)) {
             record.setThrown(e);
         }
-        record.setLoggerName(Loggers.CRS_FACTORY);
-        Logging.log(CRS.class, "getAuthorityFactory", record);
+        Logging.completeAndLog(LOGGER, CRS.class, "getAuthorityFactory", record);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index 049d562e5f..f1171ae393 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.logging.Filter;
+import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import org.opengis.util.FactoryException;
 import org.opengis.geometry.Envelope;
@@ -90,8 +91,6 @@ import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.Static;
 
-import static java.util.logging.Logger.getLogger;
-
 // Branch-dependent imports
 import org.opengis.geometry.Geometry;
 
@@ -145,6 +144,11 @@ import org.opengis.geometry.Geometry;
  * @since   0.3
  */
 public final class CRS extends Static {
+    /**
+     * The logger for referencing operations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Modules.REFERENCING);
+
     /**
      * Do not allow instantiation of this class.
      */
@@ -436,7 +440,7 @@ public final class CRS extends Static {
                         record.setSourceClassName(CRS.class.getName());
                         record.setSourceMethodName("fromAuthority");
                         if (warningFilter.isLoggable(record)) {
-                            getLogger(Modules.REFERENCING).log(record);
+                            LOGGER.log(record);
                         }
                     }
                 }
@@ -1455,6 +1459,6 @@ check:  while (lower != 0 || upper != dimension) {
      * <strong>must</strong> have a reasonable fallback (otherwise it should propagate the exception).
      */
     private static void unexpectedException(final String methodName, final Exception exception) {
-        Logging.unexpectedException(getLogger(Modules.REFERENCING), CRS.class, methodName, exception);
+        Logging.unexpectedException(LOGGER, CRS.class, methodName, exception);
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
index 7b7a91f838..6a291598f8 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
@@ -73,7 +73,6 @@ import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.system.Modules;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.util.OptionalCandidate;
 import org.apache.sis.util.resources.Vocabulary;
@@ -86,7 +85,6 @@ import org.apache.sis.math.MathFunctions;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Units;
 
-import static java.util.logging.Logger.getLogger;
 import static java.util.Collections.singletonMap;
 import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
 import static org.apache.sis.internal.util.StandardDateFormat.MILLISECONDS_PER_DAY;
@@ -145,7 +143,7 @@ import static org.apache.sis.internal.util.StandardDateFormat.MILLISECONDS_PER_D
  * </table></blockquote>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see org.apache.sis.referencing.factory.CommonAuthorityFactory
  *
@@ -524,7 +522,7 @@ public enum CommonCRS {
             if (code != null) try {
                 epsg = Integer.parseInt(code);
             } catch (NumberFormatException e) {
-                Logging.recoverableException(getLogger(Modules.REFERENCING), CommonCRS.class, "forDatum", e);
+                Logging.recoverableException(AuthorityFactories.LOGGER, CommonCRS.class, "forDatum", e);
             }
         }
         for (final CommonCRS c : values()) {
@@ -2050,7 +2048,6 @@ public enum CommonCRS {
             // Append the stack trace only if the exception is the the one we expect when the factory is not available.
             record.setThrown(e);
         }
-        record.setLoggerName(Loggers.CRS_FACTORY);
-        Logging.log(caller.getClass(), method, record);
+        Logging.completeAndLog(AuthorityFactories.LOGGER, caller.getClass(), method, record);
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
index 7f580714ae..fbdcc41ce7 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
@@ -42,7 +42,6 @@ import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.DefinitionURI;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.metadata.Identifiers;
 import org.apache.sis.internal.metadata.NameMeaning;
 import org.apache.sis.internal.metadata.NameToIdentifier;
@@ -51,7 +50,6 @@ import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
 import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
 import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.internal.util.CollectionsExt.nonNull;
 
 
@@ -60,7 +58,7 @@ import static org.apache.sis.internal.util.CollectionsExt.nonNull;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Guilhem Legal (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see CRS
  * @see org.apache.sis.geometry.Envelopes
@@ -579,7 +577,7 @@ public final class IdentifiedObjects extends Static {
      * Logs a warning for a non-critical error. The callers should have a fallback.
      */
     private static void warning(final String method, final Exception e) {
-        Logging.recoverableException(getLogger(Modules.REFERENCING), IdentifiedObjects.class, method, e);
+        Logging.recoverableException(CRS.LOGGER, IdentifiedObjects.class, method, e);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ExplicitParameters.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ExplicitParameters.java
index c2359f9560..dc2f738635 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ExplicitParameters.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/ExplicitParameters.java
@@ -28,20 +28,17 @@ import org.apache.sis.referencing.operation.DefaultOperationMethod;
 import org.apache.sis.internal.referencing.WKTKeywords;
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Temporary object for formatting the projection method and parameters inside a {@code Conversion} element.
  * This object formats only the explicit parameters. Implicit parameters derived from source ellipsoid are omitted.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.6
  */
 final class ExplicitParameters extends FormattableObject {
@@ -106,19 +103,19 @@ final class ExplicitParameters extends FormattableObject {
                             value = ((ParameterValue<?>) param).doubleValue(ellipsoid.getAxisUnit());
                         } catch (IllegalStateException e) {
                             /*
-                             * May happen if the 'conversionFromBase' parameter group does not provide values
+                             * May happen if the `conversionFromBase` parameter group does not provide values
                              * for "semi_major" or "semi_minor" axis length. This should not happen with SIS
                              * implementation, but may happen with user-defined map projection implementations.
                              * Since the intent of this check was to skip those parameters anyway, it is okay
                              * for the purpose of WKT formatting if there are no parameters for axis lengths.
                              */
-                            Logging.recoverableException(getLogger(Loggers.WKT), DefaultProjectedCRS.class, "formatTo", e);
+                            Logging.recoverableException(WKTUtilities.LOGGER, DefaultProjectedCRS.class, "formatTo", e);
                             continue;
                         }
                         if (Double.isNaN(value)) {
                             continue;
                         }
-                        final double expected = (name == Constants.SEMI_MINOR)   // using '==' is okay here.
+                        final double expected = (name == Constants.SEMI_MINOR)   // using `==` is okay here.
                                 ? ellipsoid.getSemiMinorAxis() : ellipsoid.getSemiMajorAxis();
                         if (value == expected) {
                             continue;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java
index ffd0f866cd..99a2b94c86 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java
@@ -73,7 +73,7 @@
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Cédric Briançon (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.4
  */
 @XmlSchema(location = "http://schemas.opengis.net/gml/3.2.1/coordinateReferenceSystems.xsd",
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
index 6e439d5f3a..93ff99ed09 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.cs;
 import java.util.Map;
 import java.util.EnumMap;
 import java.util.Arrays;
+import java.util.logging.Logger;
 import javax.measure.Unit;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
@@ -51,7 +52,6 @@ import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.util.ArgumentChecks.*;
 
 
@@ -75,7 +75,7 @@ import static org.apache.sis.util.ArgumentChecks.*;
  * objects and passed between threads without synchronization.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.0
+ * @version 1.4
  *
  * @see DefaultCoordinateSystemAxis
  * @see org.apache.sis.referencing.crs.AbstractCRS
@@ -98,6 +98,11 @@ import static org.apache.sis.util.ArgumentChecks.*;
     DefaultUserDefinedCS.class
 })
 public class AbstractCS extends AbstractIdentifiedObject implements CoordinateSystem {
+    /**
+     * The logger for referencing operations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Modules.REFERENCING);
+
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -421,7 +426,7 @@ public class AbstractCS extends AbstractIdentifiedObject implements CoordinateSy
                  * Other exceptions would probably be more serious errors, but it still non-fatal
                  * for this method since we can continue with what Normalizer created.
                  */
-                Logging.recoverableException(getLogger(Modules.REFERENCING), getClass(), "forConvention", e);
+                Logging.recoverableException(LOGGER, getClass(), "forConvention", e);
             }
         }
         return this;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
index 3ab2ddb261..871745bda0 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
@@ -42,7 +42,6 @@ import org.apache.sis.util.Classes;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.NullArgumentException;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.internal.referencing.Formulas;
@@ -50,8 +49,6 @@ import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Utility methods working on {@link CoordinateSystem} objects and their axes.
@@ -686,7 +683,7 @@ forDim: switch (axes.length) {
                                     break forDim;
                                 }
                             } catch (IncommensurableException e) {      // Should never happen since we checked that units are angular.
-                                Logging.unexpectedException(getLogger(Modules.REFERENCING), CoordinateSystems.class, "getEpsgCode", e);
+                                Logging.unexpectedException(AbstractCS.LOGGER, CoordinateSystems.class, "getEpsgCode", e);
                                 break forDim;
                             }
                         }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
index 4f1951283b..2947870526 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
@@ -25,15 +25,12 @@ import org.apache.sis.measure.Longitude;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.referencing.AxisDirections;
 import org.apache.sis.internal.referencing.WKTKeywords;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Parses {@linkplain AxisDirection axis direction} of the kind <cite>"South along 90 deg East"</cite>.
@@ -46,7 +43,7 @@ import static java.util.logging.Logger.getLogger;
  * ISO 19162:2015 §7.5.4(iv) - WKT 2 formatting.
  *
  * @author  Martin Desruisseaux (IRD)
- * @version 1.2
+ * @version 1.4
  * @since   0.4
  */
 final class DirectionAlongMeridian extends FormattableObject implements Comparable<DirectionAlongMeridian> {
@@ -124,7 +121,7 @@ final class DirectionAlongMeridian extends FormattableObject implements Comparab
         try {
             candidate = parse(direction.name());
         } catch (IllegalArgumentException e) {
-            Logging.recoverableException(getLogger(Modules.REFERENCING), DirectionAlongMeridian.class, "parse", e);
+            Logging.recoverableException(AbstractCS.LOGGER, DirectionAlongMeridian.class, "parse", e);
             return null;
         }
         if (candidate != null) {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
index 71e7269752..1e1b836808 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.Objects;
+import java.util.logging.Logger;
 import java.time.Instant;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
@@ -51,7 +52,6 @@ import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.io.wkt.Formatter;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNullElement;
@@ -127,7 +127,7 @@ import static org.apache.sis.internal.referencing.WKTUtilities.toFormattable;
  * constants.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.1
+ * @version 1.4
  *
  * @see DefaultEllipsoid
  * @see DefaultPrimeMeridian
@@ -142,6 +142,13 @@ import static org.apache.sis.internal.referencing.WKTUtilities.toFormattable;
 })
 @XmlRootElement(name = "GeodeticDatum")
 public class DefaultGeodeticDatum extends AbstractDatum implements GeodeticDatum {
+    /**
+     * The logger for coordinate operations.
+     *
+     * @see #getPositionVectorTransformation(GeodeticDatum, Extent)
+     */
+    private static final Logger LOGGER = Logger.getLogger(Loggers.COORDINATE_OPERATION);
+
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -299,7 +306,7 @@ public class DefaultGeodeticDatum extends AbstractDatum implements GeodeticDatum
         ellipsoid     = datum.getEllipsoid();
         primeMeridian = datum.getPrimeMeridian();
         bursaWolf     = (datum instanceof DefaultGeodeticDatum) ? ((DefaultGeodeticDatum) datum).bursaWolf : null;
-        // No need to clone the 'bursaWolf' array since it is read only.
+        // No need to clone the `bursaWolf` array since it is read only.
     }
 
     /**
@@ -440,10 +447,9 @@ public class DefaultGeodeticDatum extends AbstractDatum implements GeodeticDatum
                 /*
                  * Should never happen because BursaWolfParameters.getPositionVectorTransformation(Date)
                  * is defined in such a way that matrix should always be invertible. If it happen anyway,
-                 * returning 'null' is allowed by this method's contract.
+                 * returning `null` is allowed by this method's contract.
                  */
-                Logging.unexpectedException(getLogger(Loggers.COORDINATE_OPERATION),
-                        DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
+                Logging.unexpectedException(LOGGER, DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
             }
             /*
              * No direct tranformation found. Search for a path through an intermediate datum.
@@ -476,8 +482,7 @@ public class DefaultGeodeticDatum extends AbstractDatum implements GeodeticDatum
                                     Matrix m = MatrixSIS.castOrCopy(step2).inverse().multiply(step1);
                                     return AnnotatedMatrix.indirect(m, useAOI);
                                 } catch (NoninvertibleMatrixException e) {
-                                    Logging.unexpectedException(getLogger(Loggers.COORDINATE_OPERATION),
-                                            DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
+                                    Logging.unexpectedException(LOGGER, DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
                                 }
                             }
                         }
@@ -709,7 +714,7 @@ public class DefaultGeodeticDatum extends AbstractDatum implements GeodeticDatum
         bursaWolf = null;
         /*
          * Ellipsoid and PrimeMeridian are mandatory for SIS working. We do not verify their presence here
-         * (because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * (because the verification would have to be done in an `afterMarshal(…)` method and throwing an
          * exception in that method causes the whole unmarshalling to fail). But the CD_GeodeticDatum
          * adapter does some verifications.
          */
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java
index a327b56a22..047b2fb21b 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java
@@ -29,7 +29,6 @@ import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.metadata.NameMeaning;
 import org.apache.sis.internal.referencing.Resources;
@@ -39,7 +38,7 @@ import org.apache.sis.internal.referencing.Resources;
  * Identification of an authority factory by its type, namespace and version.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.4
  * @since   0.7
  */
 final class AuthorityFactoryIdentifier {
@@ -281,8 +280,8 @@ final class AuthorityFactoryIdentifier {
      * as the source of the log since it is the nearest public API.
      */
     private void log(final LogRecord record) {
-        record.setLoggerName(Loggers.CRS_FACTORY);
-        Logging.log(MultiAuthoritiesFactory.class, "getAuthorityFactory", record);
+        Logging.completeAndLog(GeodeticAuthorityFactory.LOGGER,
+                MultiAuthoritiesFactory.class, "getAuthorityFactory", record);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
index 5b62bd8ca0..792d6b4196 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
@@ -44,7 +44,6 @@ import org.apache.sis.internal.referencing.provider.TransverseMercator.Zoner;
 import org.apache.sis.internal.referencing.GeodeticObjectBuilder;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.measure.Units;
 import org.apache.sis.referencing.CommonCRS;
@@ -54,8 +53,6 @@ import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.SimpleInternationalString;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Creates coordinate reference systems in the "{@code OGC}", "{@code CRS}" or {@code "AUTO(2)"} namespaces.
@@ -311,7 +308,7 @@ public class CommonAuthorityFactory extends GeodeticAuthorityFactory implements
             code = parsed.localCode;
             code = parsed.isNumeric ? format(Integer.parseInt(code)) : format(code);
         } catch (NoSuchAuthorityCodeException | NumberFormatException e) {
-            Logging.ignorableException(getLogger(Loggers.CRS_FACTORY), CommonAuthorityFactory.class, "reformat", e);
+            Logging.ignorableException(LOGGER, CommonAuthorityFactory.class, "reformat", e);
             return null;
         }
         return code;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
index 7ab474133a..128302618d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
@@ -57,15 +57,12 @@ import org.apache.sis.internal.system.DelayedExecutor;
 import org.apache.sis.internal.system.DelayedRunnable;
 import org.apache.sis.internal.system.Configuration;
 import org.apache.sis.internal.system.Shutdown;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.StandardDateFormat;
 import org.apache.sis.util.logging.PerformanceLevel;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.resources.Messages;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * A concurrent authority factory that caches all objects created by another factory.
@@ -98,7 +95,7 @@ import static java.util.logging.Logger.getLogger;
  * Subclasses should select the interfaces that they choose to implement.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @param <DAO>  the type of factory used as Data Access Object (DAO).
  *
@@ -502,8 +499,7 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa
                 } else {
                     record = resources.getLogRecord(level, Messages.Keys.CreateDuration_2, type, duration);
                 }
-                record.setLoggerName(Loggers.CRS_FACTORY);
-                Logging.log(getClass(), caller, record);
+                Logging.completeAndLog(LOGGER, getClass(), caller, record);
             }
         }
         assert usage.depth >= 0 : usage;
@@ -663,8 +659,7 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa
      * @param  exception  the exception that occurred while closing a Data Access Object.
      */
     static void unexpectedException(final String method, final Exception exception) {
-        Logging.unexpectedException(getLogger(Loggers.CRS_FACTORY),
-                ConcurrentAuthorityFactory.class, method, exception);
+        Logging.unexpectedException(LOGGER, ConcurrentAuthorityFactory.class, method, exception);
     }
 
     /**
@@ -758,8 +753,7 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa
             if (!(e instanceof UnavailableFactoryException)) {
                 record.setThrown(e);
             }
-            record.setLoggerName(Loggers.CRS_FACTORY);
-            Logging.log(ConcurrentAuthorityFactory.class, "getAuthority", record);
+            Logging.completeAndLog(LOGGER, ConcurrentAuthorityFactory.class, "getAuthority", record);
             c = null;
         }
         return c;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
index aaceee6fd1..71a7c5325a 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.factory;
 
 import java.util.Set;
+import java.util.logging.Logger;
 import javax.measure.Unit;
 import org.opengis.referencing.*;
 import org.opengis.referencing.cs.*;
@@ -30,6 +31,7 @@ import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.util.FactoryException;
 import org.opengis.util.InternationalString;
 import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
@@ -62,10 +64,15 @@ import org.apache.sis.util.Classes;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 0.8
+ * @version 1.4
  * @since   0.7
  */
 public abstract class GeodeticAuthorityFactory extends AbstractFactory implements AuthorityFactory {
+    /**
+     * The logger to use for reporting object creations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.CRS_FACTORY);
+
     /**
      * Creates a new authority factory for geodetic objects.
      */
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
index b01f843b37..527e0811cb 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
@@ -58,6 +58,7 @@ import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.io.wkt.Parser;
 import org.apache.sis.util.Exceptions;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.xml.XML;
 
 
@@ -187,7 +188,7 @@ import org.apache.sis.xml.XML;
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Guilhem Legal (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.6
  */
 public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory, Parser {
@@ -315,10 +316,8 @@ public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory
                         (id != null) ? Messages.Keys.CreatedIdentifiedObject_3
                                      : Messages.Keys.CreatedNamedObject_2,
                         c.getInterface(), c.getName().getCode(), id);
-                record.setSourceClassName(GeodeticObjectFactory.class.getCanonicalName());
-                record.setSourceMethodName(caller);
-                record.setLoggerName(LOGGER.getName());
-                LOGGER.log(record);
+
+                Logging.completeAndLog(LOGGER, GeodeticObjectFactory.class, caller, record);
             }
         }
         return c;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
index 750235fa81..789e076243 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java
@@ -29,7 +29,6 @@ import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.system.Semaphores;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.util.logging.Logging;
@@ -58,7 +57,7 @@ import org.apache.sis.util.Utilities;
  * is thread-safe. If concurrent searches are desired, then a new instance should be created for each thread.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @see GeodeticAuthorityFactory#newIdentifiedObjectFinder()
  * @see IdentifiedObjects#newFinder(String)
@@ -592,8 +591,7 @@ public class IdentifiedObjectFinder {
          * use `getMessage()` instead of `getLocalizedMessage()` for
          * giving preference to the locale of system administrator.
          */
-        final LogRecord record = new LogRecord(Level.FINER, exception.getMessage());
-        record.setLoggerName(Loggers.CRS_FACTORY);
-        Logging.log(IdentifiedObjectFinder.class, "find", record);
+        Logging.completeAndLog(GeodeticAuthorityFactory.LOGGER, IdentifiedObjectFinder.class,
+                               "find", new LogRecord(Level.FINER, exception.getMessage()));
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectSet.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectSet.java
index b3b10dc99d..94623b0880 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectSet.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/IdentifiedObjectSet.java
@@ -35,7 +35,6 @@ import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Messages;
 import org.apache.sis.util.collection.BackingStoreException;
@@ -78,7 +77,7 @@ import org.apache.sis.util.Classes;
  * if they intent to cache {@code IdentifiedObjectSet} instances.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 1.4
  *
  * @param <T>  the type of objects to be included in this set.
  *
@@ -299,13 +298,12 @@ public class IdentifiedObjectSet<T extends IdentifiedObject> extends AbstractSet
                 }
                 final LogRecord record = Messages.getResources(getLocale()).getLogRecord(Level.WARNING,
                         Messages.Keys.CanNotInstantiateForIdentifier_3, type, code, getCause(exception));
-                record.setLoggerName(Loggers.CRS_FACTORY);
-                Logging.log(IdentifiedObjectSet.class, "createObject", record);
+                Logging.completeAndLog(GeodeticAuthorityFactory.LOGGER, IdentifiedObjectSet.class, "createObject", record);
             }
             synchronized (objects) {
                 if (success) {
                     /*
-                     * The check for 'containsKey' is a paranoiac check in case the element has been removed
+                     * The check for `containsKey` is a paranoiac check in case the element has been removed
                      * in another thread while we were creating the object. This is likely to be unnecessary
                      * in the vast majority of cases where the set of codes is never modified after this set
                      * has been published. However if someone decided to do such concurrent modifications,
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
index f6f47c917c..3a06624a40 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
@@ -45,7 +45,6 @@ import org.opengis.metadata.extent.Extent;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.util.FactoryException;
 import org.opengis.util.InternationalString;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.AbstractIterator;
 import org.apache.sis.internal.util.DefinitionURI;
@@ -1509,8 +1508,7 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements
          */
         final LogRecord record = Resources.forLocale(null).getLogRecord(Level.WARNING,
                 Resources.Keys.MismatchedOperationFactories_2, sourceCRS, targetCRS);
-        record.setLoggerName(Loggers.CRS_FACTORY);
-        Logging.log(MultiAuthoritiesFactory.class, "createFromCoordinateReferenceSystemCodes", record);
+        Logging.completeAndLog(LOGGER, MultiAuthoritiesFactory.class, "createFromCoordinateReferenceSystemCodes", record);
         return super.createFromCoordinateReferenceSystemCodes(sourceCRS, targetCRS);
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/CloseableReference.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/CloseableReference.java
index 806c59aa58..38f1f49082 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/CloseableReference.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/CloseableReference.java
@@ -19,13 +19,10 @@ package org.apache.sis.referencing.factory.sql;
 import java.lang.ref.WeakReference;
 import java.sql.SQLException;
 import java.sql.Statement;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.system.ReferenceQueueConsumer;
 import org.apache.sis.util.Disposable;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Closes JDBC statements when {@link AuthorityCodes} is garbage collected.
@@ -34,7 +31,7 @@ import static java.util.logging.Logger.getLogger;
  * be closed.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @see EPSGFactory#canClose(EPSGDataAccess)
  *
@@ -105,7 +102,7 @@ final class CloseableReference extends WeakReference<AuthorityCodes> implements
              * Pretend that the logging come from AuthorityCodes because it is closer to a public API (or at
              * least, easier to guess that it is related to the EPSGDataAccess.getAuthorityCodes() method).
              */
-            Logging.unexpectedException(getLogger(Loggers.CRS_FACTORY), AuthorityCodes.class, "close", exception);
+            Logging.unexpectedException(EPSGDataAccess.LOGGER, AuthorityCodes.class, "close", exception);
         }
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
index 6d664c600e..7073e934a9 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java
@@ -43,7 +43,6 @@ import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.metadata.sql.SQLUtilities;
 import org.apache.sis.internal.referencing.Formulas;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.IdentifiedObjects;
@@ -54,7 +53,6 @@ import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.internal.metadata.NameToIdentifier.Simplifier.ESRI_DATUM_PREFIX;
 
 
@@ -63,7 +61,7 @@ import static org.apache.sis.internal.metadata.NameToIdentifier.Simplifier.ESRI_
  * This is used for finding the EPSG code of a given Coordinate Reference System or other geodetic object.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.7
  */
 final class EPSGCodeFinder extends IdentifiedObjectFinder {
@@ -143,9 +141,9 @@ final class EPSGCodeFinder extends IdentifiedObjectFinder {
             for (final IdentifiedObject dep : find) {
                 Identifier id = IdentifiedObjects.getIdentifier(dep, Citations.EPSG);
                 if (id != null) try {                                                   // Should never be null, but let be safe.
-                    filters.add(Integer.parseInt(id.getCode()));
+                    filters.add(Integer.valueOf(id.getCode()));
                 } catch (NumberFormatException e) {
-                    Logging.recoverableException(getLogger(Loggers.CRS_FACTORY), EPSGCodeFinder.class, "getCodeCandidates", e);
+                    Logging.recoverableException(EPSGDataAccess.LOGGER, EPSGCodeFinder.class, "getCodeCandidates", e);
                 }
             }
             if (!filters.isEmpty()) {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
index 7985cabf94..46658ed855 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
@@ -30,6 +30,7 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
 import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
@@ -118,7 +119,6 @@ import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.measure.Units;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.util.Utilities.equalsIgnoreMetadata;
 import static org.apache.sis.internal.util.StandardDateFormat.UTC;
 import static org.apache.sis.internal.referencing.ServicesForMetadata.CONNECTION;
@@ -158,7 +158,7 @@ import static org.apache.sis.internal.referencing.ServicesForMetadata.CONNECTION
  * @author  Matthias Basler
  * @author  Andrea Aime (TOPP)
  * @author  Johann Sorel (Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @see <a href="https://sis.apache.org/tables/CoordinateReferenceSystems.html">List of authority codes</a>
  *
@@ -167,6 +167,11 @@ import static org.apache.sis.internal.referencing.ServicesForMetadata.CONNECTION
 public class EPSGDataAccess extends GeodeticAuthorityFactory implements CRSAuthorityFactory,
         CSAuthorityFactory, DatumAuthorityFactory, CoordinateOperationAuthorityFactory, Localized, AutoCloseable
 {
+    /**
+     * The logger for factory operation.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.CRS_FACTORY);
+
     /**
      * The vertical datum type, which is fixed to a hard-coded value for all vertical datum for now.
      * Note that vertical datum type is no longer part of ISO 19111:2007.
@@ -490,7 +495,7 @@ addURIs:    for (int i=0; ; i++) {
                     r.setLinkage(new URI(url));
                 } catch (URISyntaxException exception) {
                     // May happen if there is spaces in the URI.
-                    Logging.recoverableException(getLogger(Loggers.CRS_FACTORY), EPSGDataAccess.class, "getAuthority", exception);
+                    Logging.recoverableException(LOGGER, EPSGDataAccess.class, "getAuthority", exception);
                 }
                 r.setFunction(function);
                 r.setDescription(description);
@@ -1093,8 +1098,7 @@ codes:  for (int i=0; i<codes.length; i++) {
         if (!quiet) {
             LogRecord record = Resources.forLocale(locale).getLogRecord(Level.WARNING, Resources.Keys.DeprecatedCode_3,
                     Constants.EPSG + Constants.DEFAULT_SEPARATOR + code, replacedBy, reason);
-            record.setLoggerName(Loggers.CRS_FACTORY);
-            Logging.log(EPSGDataAccess.class, method, record);
+            Logging.completeAndLog(LOGGER, EPSGDataAccess.class, method, record);
         }
         return (String) replacedBy;
     }
@@ -1969,8 +1973,7 @@ codes:  for (int i=0; i<codes.length; i++) {
                         // Log a warning and create the ellipsoid using the inverse flattening.
                         final LogRecord record = resources().getLogRecord(Level.WARNING,
                                 Resources.Keys.AmbiguousEllipsoid_1, Constants.EPSG + Constants.DEFAULT_SEPARATOR + code);
-                        record.setLoggerName(Loggers.CRS_FACTORY);
-                        Logging.log(EPSGDataAccess.class, "createEllipsoid", record);
+                        Logging.completeAndLog(LOGGER, EPSGDataAccess.class, "createEllipsoid", record);
                     }
                     ellipsoid = owner.datumFactory.createFlattenedSphere(properties, semiMajorAxis, inverseFlattening, unit);
                 }
@@ -3335,7 +3338,7 @@ next:                   while (r.next()) {
      * @param exception  the exception to log.
      */
     private static void unexpectedException(final String method, final Exception exception) {
-        Logging.unexpectedException(getLogger(Loggers.CRS_FACTORY), EPSGDataAccess.class, method, exception);
+        Logging.unexpectedException(LOGGER, EPSGDataAccess.class, method, exception);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
index 88d67cdb4f..ea7dd0497a 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
@@ -45,7 +45,6 @@ import org.apache.sis.internal.util.Constants;
 import org.apache.sis.referencing.factory.ConcurrentAuthorityFactory;
 import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.util.resources.Messages;
-import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.Exceptions;
@@ -454,7 +453,7 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess> impl
         Connection connection = null;
         try {
             connection = dataSource.getConnection();
-            Logging.log(EPSGFactory.class, "newDataAccess", Initializer.connected(connection.getMetaData()));
+            Initializer.connected(connection.getMetaData(), EPSGFactory.class, "newDataAccess");
             SQLTranslator tr = translator;
             if (tr == null) {
                 synchronized (this) {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
index ca76814b93..6b9ba3c510 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
@@ -38,7 +38,6 @@ import org.apache.sis.setup.InstallationResources;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.system.Fallback;
 import org.apache.sis.internal.system.DataDirectory;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.Constants;
 
@@ -64,7 +63,7 @@ import org.apache.sis.internal.util.Constants;
  * </ol>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.4
  * @since   0.7
  */
 public abstract class InstallationScriptProvider extends InstallationResources {
@@ -263,8 +262,7 @@ public abstract class InstallationScriptProvider extends InstallationResources {
      * {@code EPSGFactory.install(…)} because it is the public API using this class.
      */
     static void log(final LogRecord record) {
-        record.setLoggerName(Loggers.CRS_FACTORY);
-        Logging.log(EPSGFactory.class, "install", record);
+        Logging.completeAndLog(EPSGDataAccess.LOGGER, EPSGFactory.class, "install", record);
     }
 
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java
index dd67935ef5..9a2542fd11 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java
@@ -55,9 +55,10 @@
  *   <li>{@code createProjectedCRS("NTF (Paris) / Lambert zone II")}</li>
  * </ul>
  *
- * <div class="note"><b>Note:</b> names may be ambiguous since the same name may be used for more than one object.
- * This is the case of <cite>"WGS 84"</cite> for example. If such an ambiguity is found, an exception will be thrown.
- * For more determinism, the numerical codes are preferred.</div>
+ * Note that names may be ambiguous since the same name may be used for more than one object.
+ * This is the case of <cite>"WGS 84"</cite> for example.
+ * If such an ambiguity is found, an exception will be thrown.
+ * For more determinism, the numerical codes are preferred.
  *
  *
  * <h2>How deprecated entries are handled</h2>
@@ -82,7 +83,7 @@
  * @author  Jody Garnett (Refractions)
  * @author  Didier Richard (IGN)
  * @author  John Grange
- * @version 1.2
+ * @version 1.4
  *
  * @see org.apache.sis.metadata.sql
  *
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
index 086c820b73..84f014ea5f 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Objects;
 import java.util.Collection;
+import java.util.logging.Logger;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import javax.xml.bind.Unmarshaller;
@@ -73,7 +74,6 @@ import org.apache.sis.internal.system.Semaphores;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.io.wkt.Convention;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.util.Utilities.deepEquals;
 
 
@@ -105,7 +105,7 @@ import static org.apache.sis.util.Utilities.deepEquals;
  * synchronization.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.6
  */
 @XmlType(name = "AbstractCoordinateOperationType", propOrder = {
@@ -128,6 +128,11 @@ public class AbstractCoordinateOperation extends AbstractIdentifiedObject implem
      */
     private static final long serialVersionUID = 1237358357729193885L;
 
+    /**
+     * The logger for coordinate operations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.COORDINATE_OPERATION);
+
     /**
      * The source CRS, or {@code null} if not available.
      *
@@ -896,8 +901,7 @@ check:      for (int isTarget=0; ; isTarget++) {        // 0 == source check; 1
                                                                        this.getTargetCRS().getCoordinateSystem()));
                             tr2 = MathTransforms.concatenate(before, tr2, after);
                         } catch (IncommensurableException | RuntimeException e) {
-                            Logging.ignorableException(getLogger(Loggers.COORDINATE_OPERATION),
-                                    AbstractCoordinateOperation.class, "equals", e);
+                            Logging.ignorableException(LOGGER, AbstractCoordinateOperation.class, "equals", e);
                         }
                         if (deepEquals(tr1, tr2, mode)) return true;
                         assert !debug || deepEquals(tr1, tr2, ComparisonMode.DEBUG);        // For locating the mismatch.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
index 6a51b769ec..96cda91c85 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
@@ -71,7 +71,6 @@ import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.provider.Affine;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.system.Semaphores;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Utilities;
@@ -81,7 +80,6 @@ import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.util.resources.Vocabulary;
 
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -106,7 +104,7 @@ import static java.util.logging.Logger.getLogger;
  * then {@link CoordinateOperationFinder} will use its own fallback.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.7
  */
 class CoordinateOperationRegistry {
@@ -1325,17 +1323,16 @@ class CoordinateOperationRegistry {
         if (record == null) {
             record = new LogRecord(Level.WARNING, exception.getLocalizedMessage());
         }
-        record.setLoggerName(Loggers.COORDINATE_OPERATION);
         /*
-         * We usually do not log the stack trace since this method should be invoked only for exceptions
-         * like NoSuchAuthorityCodeException or MissingFactoryResourceException, for which the message
-         * is descriptive enough. But we make a special case for NoninvertibleTransformException since
+         * We usually do not log the stack trace because this method should be invoked only for exceptions
+         * such as NoSuchAuthorityCodeException or MissingFactoryResourceException, for which the message
+         * is descriptive enough. But we make a special case for NoninvertibleTransformException because
          * its cause may have deeper root.
          */
         if (exception instanceof NoninvertibleTransformException) {
             record.setThrown(exception);
         }
-        Logging.log(CoordinateOperationFinder.class, "createOperations", record);
+        Logging.completeAndLog(AbstractCoordinateOperation.LOGGER, CoordinateOperationFinder.class, "createOperations", record);
     }
 
     /**
@@ -1347,7 +1344,7 @@ class CoordinateOperationRegistry {
      * @param  exception  the exception which occurred, or {@code null} if a {@code record} is specified instead.
      */
     static void recoverableException(final String method, final Exception exception) {
-        Logging.recoverableException(getLogger(Loggers.COORDINATE_OPERATION),
+        Logging.recoverableException(AbstractCoordinateOperation.LOGGER,
                 CoordinateOperationFinder.class, method, exception);
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
index 7a82723003..530056f8cd 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.HashMap;
 import java.util.Objects;
 import java.util.regex.Pattern;
+import java.util.logging.Logger;
 import java.io.Serializable;
 import java.lang.reflect.Modifier;
 import org.opengis.metadata.Identifier;
@@ -63,7 +64,6 @@ import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
 
 import static java.lang.Math.*;
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -996,9 +996,9 @@ public abstract class NormalizedProjection extends AbstractMathTransform2D imple
                     }
                 }
             } catch (NoninvertibleTransformException e) {
-                Logging.recoverableException(getLogger(Loggers.COORDINATE_OPERATION),
-                        (projection instanceof NormalizedProjection) ? NormalizedProjection.class : projection.getClass(),
-                        "tryConcatenate", e);
+                final Logger LOGGER = Logger.getLogger(Loggers.COORDINATE_OPERATION);   // Defined in base class but field is inaccessible.
+                final Class<?> caller = (projection instanceof NormalizedProjection) ? NormalizedProjection.class : projection.getClass();
+                Logging.recoverableException(LOGGER, caller, "tryConcatenate", e);
             }
         }
         return null;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
index e39fac97e4..eec70e40c4 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.operation.transform;
 import java.util.List;
 import java.util.Arrays;
 import java.util.Optional;
+import java.util.logging.Logger;
 import org.opengis.util.FactoryException;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
@@ -39,6 +40,7 @@ import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.referencing.WKTKeywords;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.ComparisonMode;
@@ -81,7 +83,7 @@ import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches;
  * running the same SIS version.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see DefaultMathTransformFactory
  * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation
@@ -91,6 +93,11 @@ import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches;
 public abstract class AbstractMathTransform extends FormattableObject
         implements MathTransform, Parameterized, LenientComparable
 {
+    /**
+     * The logger for coordinate operations.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.COORDINATE_OPERATION);
+
     /**
      * Maximum buffer size when creating temporary arrays. Must not be too big, otherwise the
      * cost of allocating the buffer may be greater than the benefit of transforming array of
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
index f051f35c9c..26b2b03fe6 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
@@ -39,7 +39,6 @@ import org.apache.sis.internal.referencing.provider.GeocentricAffine;
 import org.apache.sis.internal.referencing.WKTKeywords;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.system.Semaphores;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.ComparisonMode;
@@ -50,8 +49,6 @@ import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Base class for concatenated transforms. Instances can be created by calls to the
@@ -62,7 +59,7 @@ import static java.util.logging.Logger.getLogger;
  * <p>Concatenated transforms are serializable if all their step transforms are serializable.</p>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see org.opengis.referencing.operation.MathTransformFactory#createConcatenatedTransform(MathTransform, MathTransform)
  *
@@ -278,8 +275,7 @@ class ConcatenatedTransform extends AbstractMathTransform implements Serializabl
                  * Ignore. The `concatenated.inverse()` method will try to compute the inverse itself,
                  * possible at the cost of more NaN values than what above code would have produced.
                  */
-                Logging.recoverableException(getLogger(Loggers.COORDINATE_OPERATION),
-                        ConcatenatedTransform.class, "create", e);
+                Logging.recoverableException(LOGGER, ConcatenatedTransform.class, "create", e);
             }
         }
         return concatenated;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
index b1e1a35e97..8e8674bb78 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
@@ -40,7 +40,6 @@ import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.referencing.WKTKeywords;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.referencing.Formulas;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.parameter.Parameters;
@@ -56,7 +55,7 @@ import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ArraysExt;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.referencing.WKTUtilities.LOGGER;
 
 
 /**
@@ -982,6 +981,6 @@ public class ContextualParameters extends Parameters implements Serializable {
      * transform.</p>
      */
     private static void unexpectedException(final IllegalStateException e) {
-        Logging.unexpectedException(getLogger(Loggers.WKT), ConcatenatedTransform.class, "formatTo", e.getCause());
+        Logging.unexpectedException(LOGGER, ConcatenatedTransform.class, "formatTo", e.getCause());
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
index 895c5ef0eb..78816976d7 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
@@ -68,7 +68,6 @@ import org.apache.sis.internal.referencing.provider.Providers;
 import org.apache.sis.internal.referencing.provider.GeographicToGeocentric;
 import org.apache.sis.internal.referencing.provider.GeocentricToGeographic;
 import org.apache.sis.internal.referencing.Resources;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.parameter.DefaultParameterValueGroup;
 import org.apache.sis.parameter.Parameterized;
@@ -88,8 +87,6 @@ import org.apache.sis.util.iso.AbstractFactory;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Low level factory for creating {@linkplain AbstractMathTransform math transforms}.
@@ -998,7 +995,7 @@ public class DefaultMathTransformFactory extends AbstractFactory implements Math
                      * from another implementation. We can safely abandon our attempt to set the inverse flattening value,
                      * since it was redundant with semi-minor axis length.
                      */
-                    Logging.recoverableException(getLogger(Loggers.COORDINATE_OPERATION),
+                    Logging.recoverableException(AbstractMathTransform.LOGGER,
                             DefaultMathTransformFactory.class, "createParameterizedTransform", e);
                 }
                 /*
@@ -1010,8 +1007,8 @@ public class DefaultMathTransformFactory extends AbstractFactory implements Math
                     final LogRecord record = Resources.forLocale(null).getLogRecord(Level.WARNING,
                             Resources.Keys.MismatchedEllipsoidAxisLength_3, ellipsoid.getName().getCode(),
                             mismatchedParam.getDescriptor().getName().getCode(), mismatchedValue);
-                    record.setLoggerName(Loggers.COORDINATE_OPERATION);
-                    Logging.log(DefaultMathTransformFactory.class, "createParameterizedTransform", record);
+                    Logging.completeAndLog(AbstractMathTransform.LOGGER,
+                            DefaultMathTransformFactory.class, "createParameterizedTransform", record);
                 }
             }
             return failure;
@@ -1231,7 +1228,7 @@ public class DefaultMathTransformFactory extends AbstractFactory implements Math
                     throw exception;
                 }
                 method = getOperationMethod(methodName);
-                Logging.recoverableException(getLogger(Loggers.COORDINATE_OPERATION),
+                Logging.recoverableException(AbstractMathTransform.LOGGER,
                         DefaultMathTransformFactory.class, "createParameterizedTransform", exception);
             }
             if (!(method instanceof MathTransformProvider)) {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/WraparoundTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/WraparoundTransform.java
index 7b4b6bcc10..cec98454b9 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/WraparoundTransform.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/WraparoundTransform.java
@@ -32,15 +32,12 @@ import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.internal.referencing.MathTransformsOrFactory;
 import org.apache.sis.internal.referencing.provider.Wraparound;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Enforces coordinate values in the range of a wraparound axis (typically longitude).
@@ -72,7 +69,7 @@ import static java.util.logging.Logger.getLogger;
  * (it may be the [0 … 360]° range, but not necessarily).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  *
  * @see org.apache.sis.geometry.Envelopes#wraparound(MathTransform, Envelope)
  *
@@ -535,7 +532,7 @@ public class WraparoundTransform extends AbstractMathTransform implements Serial
                 }
             } catch (NoninvertibleTransformException e) {
                 // Should not happen. But if it is the case, just abandon the optimization effort.
-                Logging.recoverableException(getLogger(Modules.REFERENCING), getClass(), "tryConcatenate", e);
+                Logging.recoverableException(LOGGER, getClass(), "tryConcatenate", e);
             }
         }
         return null;
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java
index 3a399c8431..a027c9c1bf 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java
@@ -23,12 +23,10 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.TimeUnit;
 import java.lang.reflect.Field;
 import org.opengis.util.FactoryException;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static java.util.logging.Logger.getLogger;
 import static org.junit.Assert.*;
 import static org.junit.Assume.assumeTrue;
 
@@ -37,7 +35,7 @@ import static org.junit.Assume.assumeTrue;
  * Tests {@link ConcurrentAuthorityFactory}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.7
  */
 @DependsOn(AuthorityFactoryProxyTest.class)
@@ -184,7 +182,7 @@ public final class ConcurrentAuthorityFactoryTest extends TestCase {
         Thread.sleep(TimeUnit.NANOSECONDS.toMillis(waitTime));
         int n = 3;
         while (factory.isCleanScheduled()) {
-            getLogger(Loggers.CRS_FACTORY)
+            ConcurrentAuthorityFactory.LOGGER
                     .warning("Execution of ConcurrentAuthorityFactory.disposeExpired() has been delayed.");
             Thread.sleep(TIMEOUT);
             System.gc();
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/TestFactorySource.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/TestFactorySource.java
index b47f3bd7ab..2351761331 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/TestFactorySource.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/TestFactorySource.java
@@ -21,13 +21,11 @@ import java.util.HashMap;
 import org.postgresql.ds.PGSimpleDataSource;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.CRSAuthorityFactory;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.metadata.sql.Initializer;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.factory.sql.EPSGFactory;
 
-import static java.util.logging.Logger.getLogger;
 import static org.junit.Assume.*;
 import static org.opengis.test.Assert.*;
 
@@ -56,7 +54,7 @@ import static org.opengis.test.Assert.*;
  * }
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.8
  */
 public final class TestFactorySource {
@@ -115,7 +113,7 @@ public final class TestFactorySource {
             assertNotNull(factory.createGeographicCRS("4326"));
         } catch (UnavailableFactoryException e) {
             isUnavailable = true;
-            getLogger(Loggers.CRS_FACTORY).warning(e.toString());
+            GeodeticAuthorityFactory.LOGGER.warning(e.toString());
             assumeNoException("No connection to EPSG dataset.", e);
         }
         return (EPSGFactory) factory;
@@ -149,7 +147,7 @@ public final class TestFactorySource {
                     factory = af;                                                           // Must be last.
                 } catch (UnavailableFactoryException e) {
                     isUnavailable = true;
-                    getLogger(Loggers.CRS_FACTORY).warning(e.toString());
+                    GeodeticAuthorityFactory.LOGGER.warning(e.toString());
                 } finally {
                     if (factory != af) {
                         af.close();
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
index 641bd5b7ac..ceafacb194 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
@@ -26,8 +26,6 @@ import java.util.logging.LogRecord;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Messages;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Sub-directories of {@code SIS_DATA} where SIS looks for EPSG database, datum shift grids and other resources.
@@ -121,11 +119,10 @@ public enum DataDirectory {
      */
     private static void log(final Level level, final Exception e, final short key, final Object... parameters) {
         final LogRecord record = Messages.getResources(null).getLogRecord(level, key, parameters);
-        record.setLoggerName(Loggers.SYSTEM);
         if (e != null) {
             record.setThrown(e);
         }
-        Logging.log(null, null, record);            // Let Logging.log(…) infers the public caller.
+        Logging.completeAndLog(SystemListener.LOGGER, null, null, record);  // Let Logging.log(…) infers the public caller.
     }
 
     /**
@@ -157,7 +154,7 @@ public enum DataDirectory {
         if (rootDirectory == null) try {
             return getenv() == null;
         } catch (SecurityException e) {
-            Logging.recoverableException(getLogger(Loggers.SYSTEM), DataDirectory.class, "isUndefined", e);
+            Logging.recoverableException(SystemListener.LOGGER, DataDirectory.class, "isUndefined", e);
         }
         return false;
     }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
index 65fd1c7af7..10c56147e6 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
@@ -25,8 +25,6 @@ import java.util.ServiceConfigurationError;
 import java.util.function.Consumer;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Default factories defined in the {@code sis-utility} module.
@@ -183,8 +181,7 @@ public final class DefaultFactories extends SystemListener {
              * We were not allowed to invoke Thread.currentThread().getContextClassLoader().
              * But ServiceLoader.load(Class) may be allowed to, since it is part of JDK.
              */
-            Logging.recoverableException(getLogger(Loggers.SYSTEM),
-                    DefaultFactories.class, "createServiceLoader", e);
+            Logging.recoverableException(SystemListener.LOGGER, DefaultFactories.class, "createServiceLoader", e);
             return ServiceLoader.load(service);
         }
     }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedExecutor.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedExecutor.java
index 3a07ae4e67..8e0d2d87a4 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedExecutor.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedExecutor.java
@@ -21,8 +21,6 @@ import java.util.concurrent.DelayQueue;
 import java.util.concurrent.BlockingQueue;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * A thread executing short tasks after some (potentially zero nanosecond) delay.
@@ -53,7 +51,7 @@ import static java.util.logging.Logger.getLogger;
  * {@code CacheTest.stress()} tests suggests that the lightweight solution is faster.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.4
  *
  * @see <a href="https://issues.apache.org/jira/browse/SIS-76">SIS-76</a>
  *
@@ -135,7 +133,7 @@ public final class DelayedExecutor extends DaemonThread {
                  * We need to test 'isKillRequested()' below.
                  */
             } catch (Throwable exception) {
-                Logging.unexpectedException(getLogger(Loggers.SYSTEM), getClass(), "run", exception);
+                Logging.unexpectedException(SystemListener.LOGGER, getClass(), "run", exception);
             }
             if (isKillRequested()) {
                 queue.clear();
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Loggers.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Loggers.java
index 8f6be5fdeb..873f81ed62 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Loggers.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Loggers.java
@@ -35,7 +35,7 @@ import org.apache.sis.util.logging.Logging;
  * However, we also have a few more specialized loggers, which are listed here.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.6
  */
 public final class Loggers extends Static {
@@ -104,6 +104,11 @@ public final class Loggers extends Static {
      */
     public static final String COORDINATE_OPERATION = "org.apache.sis.referencing.operation";
 
+    /**
+     * The logger name for operation related to parameters.
+     */
+    public static final String PARAMETER = "org.apache.sis.parameter";
+
     /*
      * For operations related to the sis-referencing modules that do not fit into
      * the CRS_FACTORY or COORDINATE_OPERATION categories, use Modules.REFERENCING.
@@ -145,7 +150,7 @@ public final class Loggers extends Static {
                  * In such case forget the problematic fields and search the next one. This is okay
                  * since this method is only for information purpose.
                  */
-                Logging.unexpectedException(Logger.getLogger(SYSTEM), Loggers.class, "getEffectiveLevels", e);
+                Logging.unexpectedException(SystemListener.LOGGER, Loggers.class, "getEffectiveLevels", e);
             }
         }
         /*
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/OptionalDependency.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/OptionalDependency.java
index d0627018bc..bc7c9964ba 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/OptionalDependency.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/OptionalDependency.java
@@ -91,7 +91,7 @@ public abstract class OptionalDependency extends SystemListener {
             final LogRecord record = Messages.getResources(null).getLogRecord(Level.CONFIG,
                     Messages.Keys.OptionalModuleNotFound_1, dependency);
             record.setLoggerName(module);
-            Logging.log(type, "getInstance", record);
+            Logging.completeAndLog(null, type, "getInstance", record);
             return null;
         } catch (ReflectiveOperationException exception) {
             // Should never happen if we didn't broke our helper class.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/ReferenceQueueConsumer.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/ReferenceQueueConsumer.java
index bbfffa2e7a..17a2fead71 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/ReferenceQueueConsumer.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/ReferenceQueueConsumer.java
@@ -21,8 +21,6 @@ import java.lang.ref.ReferenceQueue;
 import org.apache.sis.util.Disposable;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * A thread processing all {@link Reference} instances enqueued in a {@link ReferenceQueue}.
@@ -48,7 +46,7 @@ import static java.util.logging.Logger.getLogger;
  *     }
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 1.4
  * @since   0.3
  */
 public final class ReferenceQueueConsumer extends DaemonThread {
@@ -128,7 +126,7 @@ public final class ReferenceQueueConsumer extends DaemonThread {
                  * We need to test 'isKillRequested()' below.
                  */
             } catch (Throwable exception) {
-                Logging.unexpectedException(getLogger(Loggers.SYSTEM), getClass(), "run", exception);
+                Logging.unexpectedException(SystemListener.LOGGER, getClass(), "run", exception);
             }
             if (isKillRequested()) {
                 break;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java
index b0004775f3..95d5669cd1 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java
@@ -22,15 +22,13 @@ import java.util.Objects;
 import java.util.concurrent.Callable;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * A central place where to manage SIS shutdown process.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Guilhem Legal (Geomatys)
- * @version 0.7
+ * @version 1.4
  * @since   0.3
  */
 public final class Shutdown extends Thread {
@@ -200,7 +198,7 @@ public final class Shutdown extends Thread {
             Threads.shutdown(System.nanoTime() + 4000);
         } catch (InterruptedException e) {
             if (caller != null) {
-                Logging.unexpectedException(getLogger(Loggers.SYSTEM), caller, "stop", e);
+                Logging.unexpectedException(SystemListener.LOGGER, caller, "stop", e);
             }
         }
         if (exception != null) {
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java
index 325391b862..4eb58b18be 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java
@@ -50,7 +50,7 @@ import org.apache.sis.util.collection.TreeTable;
  * eventually perform some operations like clearing a cache.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.4
  * @since   0.3
  */
 public final class Supervisor extends StandardMBean implements SupervisorMBean {
@@ -100,8 +100,7 @@ public final class Supervisor extends StandardMBean implements SupervisorMBean {
             } catch (SecurityException e) {
                 record = new LogRecord(Level.CONFIG, e.toString());
             }
-            record.setLoggerName(Loggers.SYSTEM);
-            Logging.log(Supervisor.class, "register", record);
+            Logging.completeAndLog(SystemListener.LOGGER, Supervisor.class, "register", record);
         }
     }
 
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/SystemListener.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/SystemListener.java
index 57b3ac1ea9..3273386ff2 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/SystemListener.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/SystemListener.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.system;
 
 import java.util.Arrays;
 import java.util.EventListener;
+import java.util.logging.Logger;
 import org.apache.sis.util.ArraysExt;
 
 
@@ -27,10 +28,15 @@ import org.apache.sis.util.ArraysExt;
  * to keep the SIS library OSGi-independent.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.6
+ * @version 1.4
  * @since   0.3
  */
 public abstract class SystemListener implements EventListener {
+    /**
+     * The logger for system events.
+     */
+    public static final Logger LOGGER = Logger.getLogger(Loggers.SYSTEM);
+
     /**
      * The listeners, or {@code null} if none.
      */
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java
index 85169f180e..6f7be07eea 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Threads.java
@@ -19,8 +19,6 @@ package org.apache.sis.internal.system;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Utilities methods for threads. This class declares in a single place every {@link ThreadGroup} used in SIS.
@@ -33,7 +31,7 @@ import static java.util.logging.Logger.getLogger;
  * dependencies the other way around.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   0.3
  */
 public final class Threads extends Static {
@@ -62,7 +60,7 @@ public final class Threads extends Static {
      */
     static final ThreadGroup DAEMONS = new ThreadGroup(SIS, "Daemons") {
         @Override public void uncaughtException(final Thread thread, final Throwable exception) {
-            Logging.severeException(getLogger(Loggers.SYSTEM), thread.getClass(), "run", exception);
+            Logging.severeException(SystemListener.LOGGER, thread.getClass(), "run", exception);
         }
     };
 
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java b/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
index aa61d98526..595da59529 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
@@ -416,7 +416,11 @@ public final class DefinitionURI {
                                 sequenceNumber = Integer.parseInt(trimWhitespaces(uri, splitAt+1, s).toString());
                                 splitAt = s;                      // Set only on success.
                             } catch (NumberFormatException e) {
-                                // Ignore. The URN is likely to be invalid, but we let parse(…) determines that.
+                                /*
+                                 * Ignore. The URN is likely to be invalid, but we let parse(…) determines that.
+                                 * Current version assumes that the URN was identifying a CRS, but future version
+                                 * could choose the logger in a more dynamic way.
+                                 */
                                 Logging.recoverableException(getLogger(Loggers.CRS_FACTORY), DefinitionURI.class, "parse", e);
                             }
                             orderedComponents.put(sequenceNumber, parse(uri, isURN, splitAt, next));
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
index ac85136eff..6ac07d4498 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
@@ -20,6 +20,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.MissingResourceException;
+import java.util.logging.Logger;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
 import javax.measure.Unit;
@@ -35,7 +36,6 @@ import org.apache.sis.util.logging.Logging;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.system.Configuration;
 
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -71,6 +71,11 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements Unit<Q>, LenientCo
      */
     private static final long serialVersionUID = -5559950920796714303L;
 
+    /**
+     * The logger for units of measurement.
+     */
+    static final Logger LOGGER = Logger.getLogger(Loggers.MEASURE);
+
     /**
      * The multiplication and division symbols used for Unicode representation.
      * Also used for internal representation of {@link #symbol}.
@@ -304,7 +309,7 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements Unit<Q>, LenientCo
         if (symbol != null) try {
             return UnitFormat.getBundle(Locale.getDefault()).getString(symbol);
         } catch (MissingResourceException e) {
-            Logging.ignorableException(getLogger(Loggers.MEASURE), AbstractUnit.class, "getName", e);
+            Logging.ignorableException(LOGGER, AbstractUnit.class, "getName", e);
             // Ignore as per this method contract.
         }
         return null;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java
index 8adfd750d2..9823f9464c 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java
@@ -25,14 +25,11 @@ import java.io.IOException;
 import javax.measure.Quantity;
 import javax.measure.Unit;
 import javax.measure.format.MeasurementParseException;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.util.FinalFieldSetter;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Parses and formats numbers with units of measurement.
@@ -227,7 +224,7 @@ public class QuantityFormat extends Format implements javax.measure.format.Quant
                     return Quantities.create(value.doubleValue(), unit);
                 }
             } catch (MeasurementParseException e) {
-                Logging.ignorableException(getLogger(Loggers.MEASURE), QuantityFormat.class, "parseObject", e);
+                Logging.ignorableException(AbstractUnit.LOGGER, QuantityFormat.class, "parseObject", e);
             }
             pos.setIndex(start);        // By `Format.parseObject(…)` method contract.
         }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java
index 65f8351f17..65755e65f4 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java
@@ -21,14 +21,11 @@ import javax.measure.Unit;
 import javax.measure.Quantity;
 import javax.measure.UnitConverter;
 import javax.measure.UnconvertibleException;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.StringBuilders;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * A quantity representable by position on a scale or line, having only magnitude.
@@ -344,7 +341,7 @@ class Scalar<Q extends Quantity<Q>> extends Number implements Quantity<Q>, Compa
                 return value == r.doubleValue();
             }
         } catch (UnconvertibleException e) {
-            Logging.ignorableException(getLogger(Loggers.MEASURE), Scalar.class, "isEquivalentTo", e);
+            Logging.ignorableException(AbstractUnit.LOGGER, Scalar.class, "isEquivalentTo", e);
             // Non-convertible quantities are not equivalent.
         }
         return false;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
index 12d2cd0dfc..a7ea2ff712 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
@@ -34,7 +34,6 @@ import javax.measure.Dimension;
 import javax.measure.Unit;
 import javax.measure.format.MeasurementParseException;
 import org.apache.sis.internal.system.Configuration;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.internal.util.FinalFieldSetter;
@@ -49,8 +48,6 @@ import org.apache.sis.util.CorruptedObjectException;
 import org.apache.sis.util.collection.WeakValueHashMap;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
-
 
 /**
  * Parses and formats units of measurement as SI symbols, URI in OGC namespace or other symbols.
@@ -653,7 +650,7 @@ appPow: if (unit == null) {
                     try {
                         label = names.getString(label);
                     } catch (MissingResourceException e) {
-                        Logging.ignorableException(getLogger(Loggers.MEASURE), UnitFormat.class, "format", e);
+                        Logging.ignorableException(AbstractUnit.LOGGER, UnitFormat.class, "format", e);
                         // Name not found; use the symbol as a fallback.
                     }
                     return toAppendTo.append(label);
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java
index 9165c05d6a..f410a6ba00 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java
@@ -31,9 +31,6 @@ import org.apache.sis.math.Fraction;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.collection.WeakValueHashMap;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Loggers;
-
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -262,7 +259,7 @@ final class UnitRegistry implements SystemOfUnits, Serializable {
         try {
             return Units.valueOf(symbols);
         } catch (MeasurementParseException e) {
-            Logging.ignorableException(getLogger(Loggers.MEASURE), UnitRegistry.class, "getUnit", e);
+            Logging.ignorableException(AbstractUnit.LOGGER, UnitRegistry.class, "getUnit", e);
             return null;
         }
     }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
index 8b542271f4..5d01627a96 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
@@ -31,13 +31,11 @@ import javax.measure.spi.SystemOfUnits;
 import javax.measure.spi.SystemOfUnitsService;
 import javax.measure.spi.FormatService;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Characters;
 
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -183,7 +181,7 @@ public class UnitServices extends ServiceProvider implements SystemOfUnitsServic
             style = org.apache.sis.measure.UnitFormat.Style.valueOf(name);
         } catch (IllegalArgumentException e) {
             // JSR-385 specification mandate that we return null.
-            Logging.recoverableException(getLogger(Loggers.MEASURE), UnitServices.class, "getUnitFormat", e);
+            Logging.recoverableException(AbstractUnit.LOGGER, UnitServices.class, "getUnitFormat", e);
             return null;
         }
         org.apache.sis.measure.UnitFormat f = new org.apache.sis.measure.UnitFormat(locale);
diff --git a/core/sis-utility/src/main/java/org/apache/sis/setup/About.java b/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
index 7f84dee8cb..2aea64bc96 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
@@ -80,7 +80,7 @@ import static org.apache.sis.internal.util.StandardDateFormat.UTC;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.4
  * @since   0.3
  */
 public enum About {
@@ -758,7 +758,7 @@ pathTree:   for (int j=0; ; j++) {
         try {
             return country ? locale.getCountry() : locale.getISO3Language();
         } catch (MissingResourceException e) {
-            Logging.ignorableException(getLogger(Loggers.LOCALIZATION), About.class, "configuration", e);
+            Logging.ignorableException(Vocabulary.LOGGER, About.class, "configuration", e);
             return null;
         }
     }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java b/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java
index f63d93277b..0133186aee 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java
@@ -349,7 +349,7 @@ public class OptionKey<T> implements Serializable {
             /*
              * This may happen if we are deserializing a stream produced by a more recent SIS library
              * than the one running in this JVM. This class should be robust to this situation, since
-             * we override the 'equals' and 'hashCode' methods. This option is likely to be ignored,
+             * we override the `equals` and `hashCode` methods. This option is likely to be ignored,
              * but options are expected to be optional...
              */
             Logging.recoverableException(getLogger(Modules.UTILITIES), OptionKey.class, "readResolve", e);
diff --git a/core/sis-utility/src/main/java/org/apache/sis/setup/package-info.java b/core/sis-utility/src/main/java/org/apache/sis/setup/package-info.java
index 36a2d54549..01f85a6d86 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/setup/package-info.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/setup/package-info.java
@@ -23,7 +23,7 @@
  * is created.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.setup;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/Locales.java b/core/sis-utility/src/main/java/org/apache/sis/util/Locales.java
index e5024abba5..724915aee2 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/Locales.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/Locales.java
@@ -28,11 +28,10 @@ import java.util.IllformedLocaleException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.internal.system.Loggers;
 
-import static java.util.logging.Logger.getLogger;
 import static org.apache.sis.util.CharSequences.trimWhitespaces;
 import static org.apache.sis.util.collection.Containers.hashMapCapacity;
+import static org.apache.sis.util.resources.IndexedResourceBundle.LOGGER;
 
 
 /**
@@ -82,7 +81,7 @@ public final class Locales extends Static {
              * Not a big deal if this operation fails (this is actually just an
              * optimization for reducing memory usage). Log a warning and stop.
              */
-            Logging.unexpectedException(getLogger(Loggers.LOCALIZATION), Locales.class, "<clinit>", exception);
+            Logging.unexpectedException(LOGGER, Locales.class, "<clinit>", exception);
         }
     }
 
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java b/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
index c7b3196d22..e260c4d150 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
@@ -88,33 +88,56 @@ public final class Logging extends Static {
 
     /**
      * Logs the given record to the logger associated to the given class.
+     *
+     * @deprecated Replaced by {@code completeAndLog(null, record, classe, method)} for encouraging
+     * the use of static {@link Logger} constants. Also the new name makes clear that the record is
+     * modified.
+     *
+     * @param  classe  the class to report as the source of the logging message.
+     * @param  method  the method to report as the source of the logging message.
+     * @param  record  the record to log.
+     */
+    @Deprecated(since="1.4", forRemoval=true)
+    public static void log(final Class<?> classe, final String method, final LogRecord record) {
+        completeAndLog(null, classe, method, record);
+    }
+
+    /**
+     * Completes the properties of the given record, then logs to the specified or inferred logger.
+     * If the {@code logger} argument is {@code null}, the logger is inferred from the other arguments.
      * This convenience method performs the following steps:
      *
      * <ul>
-     *   <li>Unconditionally {@linkplain LogRecord#setSourceClassName(String) set the source class name}
-     *       to the {@linkplain Class#getCanonicalName() canonical name} of the given class;</li>
-     *   <li>Unconditionally {@linkplain LogRecord#setSourceMethodName(String) set the source method name}
-     *       to the given value;</li>
-     *   <li>Get the logger for the {@linkplain LogRecord#getLoggerName() logger name} if specified,
-     *       or for the {@code classe} package name otherwise;</li>
-     *   <li>{@linkplain LogRecord#setLoggerName(String) Set the logger name} of the given record,
-     *       if not already set;</li>
-     *   <li>{@linkplain Logger#log(LogRecord) Log} the modified record.</li>
+     *   <li>{@linkplain LogRecord#setSourceClassName(String) Set the source class name}
+     *       to the {@linkplain Class#getCanonicalName() canonical name} of the given class.</li>
+     *   <li>{@linkplain LogRecord#setSourceMethodName(String) Set the source method name}
+     *       to the given value.</li>
+     *   <li>{@linkplain LogRecord#setLoggerName(String) Set the logger name}
+     *       to the {@linkplain Logger#getName() name} of the given logger if non null.
+     *       Otherwise use the {@linkplain Class#getPackageName() package name of the class}.</li>
+     *   <li>{@linkplain Logger#log(LogRecord) Log} the modified record to the specified {@code logger} if non null,
+     *       or to the logger specified by the {@linkplain LogRecord#getLoggerName() logger name} otherwise.</li>
      * </ul>
      *
+     * @param  logger  the logger where to log, or {@code null} for inferring from the logger or package name.
      * @param  classe  the class to report as the source of the logging message.
      * @param  method  the method to report as the source of the logging message.
-     * @param  record  the record to log.
+     * @param  record  the record to complete and log.
+     *
+     * @since 1.4
      */
-    public static void log(final Class<?> classe, final String method, final LogRecord record) {
+    public static void completeAndLog(Logger logger, final Class<?> classe, final String method, final LogRecord record) {
         ArgumentChecks.ensureNonNull("record", record);
-        final String loggerName = record.getLoggerName();
-        Logger logger;
-        if (loggerName == null) {
-            logger = getLogger(classe);
+        if (logger != null) {
             record.setLoggerName(logger.getName());
         } else {
-            logger = Logger.getLogger(loggerName);
+            final String loggerName = record.getLoggerName();
+            if (loggerName == null) {
+                logger = getLogger(classe);
+                record.setLoggerName(logger.getName());
+            } else {
+                logger = Logger.getLogger(loggerName);
+            }
         }
         if (classe != null && method != null) {
             record.setSourceClassName(classe.getCanonicalName());
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
index 11580346f1..ef618c53a4 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
@@ -29,6 +29,7 @@ import java.util.MissingResourceException;
 import java.util.NoSuchElementException;
 import java.util.ResourceBundle;
 import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.lang.reflect.Modifier;
 import javax.measure.Unit;
@@ -50,7 +51,6 @@ import org.apache.sis.internal.util.Strings;
 import org.apache.sis.measure.RangeFormat;
 import org.apache.sis.measure.Range;
 
-import static java.util.logging.Logger.getLogger;
 
 
 /**
@@ -79,10 +79,15 @@ import static java.util.logging.Logger.getLogger;
  * multiple threads.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 public class IndexedResourceBundle extends ResourceBundle implements Localized {
+    /**
+     * The logger for localization events.
+     */
+    public static final Logger LOGGER = Logger.getLogger(Loggers.LOCALIZATION);
+
     /**
      * Key used in properties map for localizing some aspects of the operation being executed.
      * The {@code getResources(Map<?,?>)} methods defined in some sub-classes will look for this property.
@@ -306,7 +311,6 @@ public class IndexedResourceBundle extends ResourceBundle implements Localized {
                     final String    baseName   = getClass().getCanonicalName();
                     final String    methodName = (key != null) ? "getObject" : "getKeys";
                     final LogRecord record     = new LogRecord(Level.FINER, "Loaded resources for {0} from bundle \"{1}\".");
-                    record.setLoggerName(Loggers.LOCALIZATION);
                     /*
                      * Loads resources from the UTF file.
                      */
@@ -322,7 +326,7 @@ public class IndexedResourceBundle extends ResourceBundle implements Localized {
                         record.setLevel  (Level.WARNING);
                         record.setMessage(exception.getMessage());              // For administrator, use system locale.
                         record.setThrown (exception);
-                        Logging.log(IndexedResourceBundle.class, methodName, record);
+                        Logging.completeAndLog(LOGGER, IndexedResourceBundle.class, methodName, record);
                         throw (MissingResourceException) new MissingResourceException(
                                 Exceptions.getLocalizedMessage(exception, locale),   // For users, use requested locale.
                                 baseName, key).initCause(exception);
@@ -341,7 +345,7 @@ public class IndexedResourceBundle extends ResourceBundle implements Localized {
                         language = "<root>";
                     }
                     record.setParameters(new String[] {language, baseName});
-                    Logging.log(IndexedResourceBundle.class, methodName, record);
+                    Logging.completeAndLog(LOGGER, IndexedResourceBundle.class, methodName, record);
                     resources = null;                                           // Not needed anymore, let GC do its job.
                 }
                 this.values = values;
@@ -377,7 +381,7 @@ public class IndexedResourceBundle extends ResourceBundle implements Localized {
                 keyID = getKeyConstants().getKeyValue(key);
             } catch (ReflectiveOperationException e) {
                 e.addSuppressed(exception);
-                Logging.recoverableException(getLogger(Loggers.LOCALIZATION), getClass(), "handleGetObject", e);
+                Logging.recoverableException(LOGGER, getClass(), "handleGetObject", e);
                 return null;                // This is okay as of 'handleGetObject' contract.
             }
         }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java
index d0eaaaa099..561200134c 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java
@@ -82,7 +82,7 @@
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see java.util.ResourceBundle
  * @see java.text.MessageFormat
diff --git a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/LandsatStoreProvider.java b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/LandsatStoreProvider.java
index 769374d131..cb16491251 100644
--- a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/LandsatStoreProvider.java
+++ b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/LandsatStoreProvider.java
@@ -19,6 +19,7 @@ package org.apache.sis.storage.landsat;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.Files;
+import java.util.logging.Logger;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.apache.sis.storage.Aggregate;
 import org.apache.sis.storage.DataStore;
@@ -42,7 +43,7 @@ import org.apache.sis.internal.storage.wkt.FirstKeywordPeek;
  * the part of the caller. However, the {@link LandsatStore} instances created by this factory are not thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.1
  */
 @StoreMetadata(formatName    = LandsatStoreProvider.NAME,
@@ -54,6 +55,13 @@ public class LandsatStoreProvider extends DataStoreProvider {
      */
     static final String NAME = "Landsat";
 
+    /**
+     * The logger used by Landsat stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.landsat");
+
     /**
      * The parameter descriptor to be returned by {@link #getOpenParameters()}.
      */
@@ -217,4 +225,12 @@ public class LandsatStoreProvider extends DataStoreProvider {
     public DataStore open(final StorageConnector connector) throws DataStoreException {
         return new LandsatStore(this, connector);
     }
+
+    /**
+     * {@return the logger used by Landsat stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
index 1417c79c74..a8d731006a 100644
--- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
+++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
@@ -18,6 +18,7 @@ package org.apache.sis.storage.geotiff;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.logging.Logger;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.apache.sis.util.Version;
 import org.apache.sis.storage.Aggregate;
@@ -42,7 +43,7 @@ import org.apache.sis.internal.util.Constants;
  * the part of the caller. However, the {@link GeoTiffStore} instances created by this factory are not thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @see GeoTiffStore
  *
@@ -63,6 +64,13 @@ public class GeoTiffStoreProvider extends DataStoreProvider {
      */
     private static final Version VERSION = new Version("6.0");
 
+    /**
+     * The logger used by GeoTIFF stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.geotiff");
+
     /**
      * The parameter descriptor to be returned by {@link #getOpenParameters()}.
      */
@@ -138,4 +146,12 @@ public class GeoTiffStoreProvider extends DataStoreProvider {
     public DataStore open(final StorageConnector connector) throws DataStoreException {
         return new GeoTiffStore(this, connector);
     }
+
+    /**
+     * {@return the logger used by GeoTIFF stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
index 47de39ea7a..676c79abea 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
@@ -41,6 +41,7 @@ import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.logging.PerformanceLevel;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.internal.util.StandardDateFormat;
@@ -57,14 +58,17 @@ import ucar.nc2.constants.CF;
  * Synchronizations are caller's responsibility.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 public abstract class Decoder extends ReferencingFactoryContainer implements Closeable {
     /**
      * The logger to use for messages other than warnings specific to the file being read.
+     * This is rarely used directly because {@code listeners.getLogger()} should be preferred.
+     *
+     * @see #listeners
      */
-    static final Logger LOGGER = Logger.getLogger(Modules.NETCDF);
+    public static final Logger LOGGER = Logger.getLogger(Modules.NETCDF);
 
     /**
      * The format name to use in error message. We use lower-case "n" because it seems to be what the netCDF community uses.
@@ -505,13 +509,11 @@ public abstract class Decoder extends ReferencingFactoryContainer implements Clo
     final void performance(final Class<?> caller, final String method, final short resourceKey, long time) {
         time = System.nanoTime() - time;
         final Level level = PerformanceLevel.forDuration(time, TimeUnit.NANOSECONDS);
-        if (LOGGER.isLoggable(level)) {
+        final Logger logger = listeners.getLogger();
+        if (logger.isLoggable(level)) {
             final LogRecord record = resources().getLogRecord(level, resourceKey,
                     getFilename(), time / (double) StandardDateFormat.NANOS_PER_SECOND);
-            record.setLoggerName(Modules.NETCDF);
-            record.setSourceClassName(caller.getCanonicalName());
-            record.setSourceMethodName(method);
-            LOGGER.log(record);
+            Logging.completeAndLog(logger, caller, method, record);
         }
     }
 
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/package-info.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/package-info.java
index f2b741492c..f9400f75d9 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/package-info.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/package-info.java
@@ -38,7 +38,7 @@
  * consistent vocabulary (more similar to the rest of Apache SIS).</p>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.internal.netcdf;
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
index 5b23216a03..14a11598fa 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
@@ -17,6 +17,7 @@
 package org.apache.sis.storage.netcdf;
 
 import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -65,7 +66,7 @@ import org.apache.sis.util.Version;
  * the part of the caller. However, the {@link NetcdfStore} instances created by this factory are not thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see NetcdfStore
  *
@@ -444,8 +445,7 @@ public class NetcdfStoreProvider extends DataStoreProvider {
             }
             final LogRecord record = Resources.forLocale(null).getLogRecord(severity, Resources.Keys.CanNotUseUCAR);
             record.setThrown(cause);
-            record.setLoggerName(Modules.NETCDF);
-            Logging.log(NetcdfStoreProvider.class, open ? "open" : "probeContent", record);
+            Logging.completeAndLog(Decoder.LOGGER, NetcdfStoreProvider.class, open ? "open" : "probeContent", record);
         }
     }
 
@@ -459,4 +459,12 @@ public class NetcdfStoreProvider extends DataStoreProvider {
         createFromUCAR  = null;
         createFromPath  = null;
     }
+
+    /**
+     * {@return the logger used by netCDF stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return Decoder.LOGGER;
+    }
 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
index 787d19b7a8..9d92d73a99 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
@@ -40,7 +40,7 @@
  * Care must be taken for avoiding confusion when using SIS and UCAR libraries together.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.storage.netcdf;
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStoreProvider.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStoreProvider.java
index dbd80652ce..1f72004120 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStoreProvider.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStoreProvider.java
@@ -19,6 +19,7 @@ package org.apache.sis.storage.sql;
 import java.util.Map;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.logging.Logger;
 import javax.sql.DataSource;
 import org.opengis.util.GenericName;
 import org.opengis.parameter.ParameterValueGroup;
@@ -50,7 +51,7 @@ import static org.apache.sis.internal.sql.feature.Database.WILDCARD;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.0
  */
 @StoreMetadata(formatName    = SQLStoreProvider.NAME,
@@ -62,6 +63,13 @@ public class SQLStoreProvider extends DataStoreProvider {
      */
     static final String NAME = "SQL";
 
+    /**
+     * The logger used by SQL stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.sql");
+
     /**
      * Name of the parameter for the list of qualified table names.
      * Values of this parameter are {@code GenericName[]}.
@@ -225,4 +233,12 @@ public class SQLStoreProvider extends DataStoreProvider {
             throw new IllegalOpenParameterException(e.getMessage(), e);
         }
     }
+
+    /**
+     * {@return the logger used by SQL stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java
index d18da528c5..a870d4b50a 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java
@@ -18,7 +18,6 @@ package org.apache.sis.internal.storage;
 
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
-import java.util.logging.Logger;
 import org.opengis.metadata.distribution.Format;
 import org.apache.sis.metadata.sql.MetadataSource;
 import org.apache.sis.metadata.sql.MetadataStoreException;
@@ -31,7 +30,7 @@ import org.apache.sis.internal.system.Modules;
  * The primary key in the {@code MD_Format} table must be the name given at construction time.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.8
  */
 public abstract class DocumentedStoreProvider extends URIDataStore.Provider {
@@ -100,7 +99,7 @@ public abstract class DocumentedStoreProvider extends URIDataStore.Provider {
                 if (listeners != null) {
                     listeners.warning(record);
                 } else {
-                    Logger.getLogger(Modules.STORAGE).log(record);
+                    getLogger().log(record);
                 }
             }
             format = super.getFormat();
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
index d651b1fae1..12106897de 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.storage.csv;
 
+import java.util.logging.Logger;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
@@ -45,7 +46,7 @@ import org.apache.sis.util.ArgumentChecks;
  * the part of the caller. However, the {@link Store} instances created by this factory are not thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.8
  */
 @StoreMetadata(formatName    = StoreProvider.NAME,
@@ -58,6 +59,13 @@ public final class StoreProvider extends URIDataStore.Provider {
      */
     static final String NAME = "CSV", MOVING = "CSV-MF";
 
+    /**
+     * The logger used by CSV stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.csv");
+
     /**
      * The object to use for verifying if the first keyword is the expected one.
      */
@@ -153,7 +161,7 @@ public final class StoreProvider extends URIDataStore.Provider {
      */
     @Override
     public ProbeResult probeContent(final StorageConnector connector) throws DataStoreException {
-        return new Peek().probeContent(this, connector);
+        return Peek.INSTANCE.probeContent(this, connector);
     }
 
     /**
@@ -193,4 +201,12 @@ public final class StoreProvider extends URIDataStore.Provider {
     protected ParameterDescriptorGroup build(final ParameterBuilder builder) {
         return builder.createGroup(LOCATION_PARAM, ENCODING, FOLIATION);
     }
+
+    /**
+     * {@return the logger used by CSV stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/AsciiGridStoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/AsciiGridStoreProvider.java
index 94178e9acc..c1e5fa9eeb 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/AsciiGridStoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/AsciiGridStoreProvider.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.storage.esri;
 
 import java.util.Map;
+import java.util.logging.Logger;
 import java.nio.ByteBuffer;
 import java.io.EOFException;
 import org.apache.sis.storage.DataStore;
@@ -38,7 +39,7 @@ import org.apache.sis.internal.storage.PRJDataStore;
  * the part of the caller. However, the {@link AsciiGridStore} instances created by this factory are not thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.2
  */
 @StoreMetadata(formatName    = AsciiGridStoreProvider.NAME,
@@ -51,6 +52,13 @@ public final class AsciiGridStoreProvider extends PRJDataStore.Provider {
      */
     static final String NAME = "ASCII Grid";
 
+    /**
+     * The logger used by ASCII grid stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.esri");
+
     /**
      * Creates a new provider.
      */
@@ -135,4 +143,12 @@ cellsize:           if (!header.containsKey(AsciiGridStore.CELLSIZE)) {
             return new AsciiGridStore(this, connector, true);
         }
     }
+
+    /**
+     * {@return the logger used by ASCII grid stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/RawRasterStoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/RawRasterStoreProvider.java
index 1ab4e082e0..ea19ec4054 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/RawRasterStoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/RawRasterStoreProvider.java
@@ -19,6 +19,7 @@ package org.apache.sis.internal.storage.esri;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.logging.Logger;
 import org.apache.sis.storage.ProbeResult;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.GridCoverageResource;
@@ -39,7 +40,7 @@ import org.apache.sis.storage.DataStore;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.2
  */
 @StoreMetadata(formatName    = RawRasterStoreProvider.NAME,
@@ -57,6 +58,13 @@ public final class RawRasterStoreProvider extends PRJDataStore.Provider {
      */
     static final String HDR = "hdr";
 
+    /**
+     * The logger used by RAW stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.esri");
+
     /**
      * Creates a new provider.
      */
@@ -111,4 +119,12 @@ public final class RawRasterStoreProvider extends PRJDataStore.Provider {
     public DataStore open(final StorageConnector connector) throws DataStoreException {
         return new RawRasterStore(this, connector);
     }
+
+    /**
+     * {@return the logger used by RAW stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/package-info.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/package-info.java
index 0cfc964885..4d3e9c6810 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/package-info.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/esri/package-info.java
@@ -46,7 +46,7 @@
  * Sub-setting parameters are ignored.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see <a href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/raster-and-images/esri-ascii-raster-format.htm">Esri ASCII raster format</a>
  * @see <a href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/raster-and-images/bil-bip-and-bsq-raster-files.htm">BIL, BIP, and BSQ raster files</a>
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/StoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/StoreProvider.java
index a477631096..8f56e6710f 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/StoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/StoreProvider.java
@@ -19,6 +19,7 @@ package org.apache.sis.internal.storage.folder;
 import java.util.EnumSet;
 import java.util.Locale;
 import java.util.TimeZone;
+import java.util.logging.Logger;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.file.Path;
@@ -58,7 +59,7 @@ import org.apache.sis.setup.OptionKey;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   0.8
  */
 @StoreMetadata(formatName    = StoreProvider.NAME,
@@ -71,6 +72,13 @@ public final class StoreProvider extends DataStoreProvider {
      */
     static final String NAME = "folder";
 
+    /**
+     * The logger used by folder stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.folder");
+
     /**
      * Description of the parameter for formatting conventions of dates and numbers.
      */
@@ -281,4 +289,12 @@ public final class StoreProvider extends DataStoreProvider {
         }
         return open(connector, pg.getValue(FORMAT), options);
     }
+
+    /**
+     * {@return the logger used by folder stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
index 7b0435fc12..b5ea37a2e6 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
@@ -19,7 +19,7 @@
  * {@link org.apache.sis.storage.DataStore} implementation for a folder containing an arbitrary number of data files.
  *
  * @author  Johann Sorel (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.8
  */
 package org.apache.sis.internal.storage.folder;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WorldFileStoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WorldFileStoreProvider.java
index 1835034661..99b1c9430d 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WorldFileStoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/WorldFileStoreProvider.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.storage.image;
 
 import java.util.Set;
 import java.util.HashSet;
+import java.util.logging.Logger;
 import java.io.IOException;
 import javax.imageio.spi.ImageReaderSpi;
 import org.apache.sis.storage.DataStoreException;
@@ -36,7 +37,7 @@ import org.apache.sis.util.ArraysExt;
  * The provider of {@link WorldFileStore} instances.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   1.2
  */
 @StoreMetadata(formatName    = WorldFileStoreProvider.NAME,
@@ -61,6 +62,13 @@ public final class WorldFileStoreProvider extends PRJDataStore.Provider {
      */
     private static final String[] SINGLE_IMAGE_FORMATS = {"PNG", "BMP", "WBMP", "JPEG"};
 
+    /**
+     * The logger used by image stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.image");
+
     /**
      * Whether the provider is allowed to create {@link GridCoverageResource} instances
      * instead of {@link Aggregate} instances.
@@ -165,4 +173,12 @@ public final class WorldFileStoreProvider extends PRJDataStore.Provider {
         }
         return ProbeResult.SUPPORTED;
     }
+
+    /**
+     * {@return the logger used by image stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java
index 3234dcfd08..96fb66993e 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java
@@ -29,7 +29,6 @@ import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.internal.storage.Resources;
 import org.apache.sis.internal.system.DelayedExecutor;
 import org.apache.sis.internal.system.DelayedRunnable;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ArraysExt;
@@ -38,7 +37,7 @@ import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.collection.RangeSet;
 import org.apache.sis.util.logging.Logging;
 
-import static java.util.logging.Logger.getLogger;
+import static org.apache.sis.internal.storage.StoreUtilities.LOGGER;
 
 
 /**
@@ -752,7 +751,7 @@ public abstract class FileCacheByteChannel implements SeekableByteChannel {
                     } else try {
                         drainAndAbort();
                     } catch (IOException e) {
-                        Logging.unexpectedException(getLogger(Modules.STORAGE), IdleConnectionCloser.class, "run", e);
+                        Logging.unexpectedException(LOGGER, IdleConnectionCloser.class, "run", e);
                     }
                 }
             }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java
index 0118959c18..797b44001f 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java
@@ -25,7 +25,7 @@
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.4
  */
 package org.apache.sis.internal.storage;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/FirstKeywordPeek.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/FirstKeywordPeek.java
index 9e3ef94e28..3eaa4a61b2 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/FirstKeywordPeek.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/FirstKeywordPeek.java
@@ -33,6 +33,7 @@ import org.apache.sis.util.Characters;
 
 /**
  * Inspects the type of a text file based on the first keyword.
+ * This base class is immutable and thread-safe (but subclasses may not be).
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.2
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
index 0079b0c555..4fcc750014 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
@@ -19,6 +19,7 @@ package org.apache.sis.internal.storage.wkt;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.logging.Logger;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
@@ -34,7 +35,7 @@ import org.apache.sis.util.Version;
  * The provider of WKT {@link Store} instances.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.7
  */
 @StoreMetadata(formatName   = StoreProvider.NAME,
@@ -46,6 +47,13 @@ public final class StoreProvider extends URIDataStore.Provider {
      */
     public static final String NAME = "WKT";
 
+    /**
+     * The logger used by WKT stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.wkt");
+
     /**
      * The object to use for verifying if the first keyword is a WKT one.
      * This object contains the set of recognized WKT keywords.
@@ -182,4 +190,12 @@ public final class StoreProvider extends URIDataStore.Provider {
     public DataStore open(final StorageConnector connector) throws DataStoreException {
         return new Store(this, connector);
     }
+
+    /**
+     * {@return the logger used by WKT stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java
index b281b1ee4d..1663565437 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java
@@ -19,7 +19,7 @@
  * {@link org.apache.sis.storage.DataStore} implementation for Well Known Text.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.7
  */
 package org.apache.sis.internal.storage.wkt;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
index abb3744c1a..f80e1c848d 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.storage.xml;
 
 import java.util.Map;
+import java.util.logging.Logger;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
@@ -42,6 +43,13 @@ public final class StoreProvider extends AbstractProvider {
      */
     public static final String NAME = "XML";
 
+    /**
+     * The logger used by XML stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.xml");
+
     /**
      * Creates a new provider.
      */
@@ -78,4 +86,12 @@ public final class StoreProvider extends AbstractProvider {
     public DataStore open(final StorageConnector connector) throws DataStoreException {
         return new Store(this, connector);
     }
+
+    /**
+     * {@return the logger used by XML stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
index 92950cfb09..56ad65df44 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
@@ -65,7 +65,7 @@ import org.apache.sis.util.resources.Errors;
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.3
  */
 public abstract class DataStoreProvider {
@@ -114,16 +114,6 @@ public abstract class DataStoreProvider {
      */
     public static final String CREATE = "create";
 
-    /**
-     * The logger where to reports warnings or change events. Created when first needed and kept
-     * by strong reference for avoiding configuration lost if the logger is garbage collected.
-     * This strategy assumes that {@code DataStoreProvider} instances are kept alive for the
-     * duration of JVM lifetime, which is the case with {@link DataStoreRegistry}.
-     *
-     * @see #getLogger()
-     */
-    private volatile Logger logger;
-
     /**
      * Creates a new provider.
      */
@@ -640,10 +630,6 @@ public abstract class DataStoreProvider {
      * @since 1.0
      */
     public Logger getLogger() {
-        Logger lg = logger;
-        if (lg == null) {
-            logger = lg = Logging.getLogger(getClass());
-        }
-        return lg;
+        return Logging.getLogger(getClass());
     }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridCoverage.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridCoverage.java
index 965b0c6308..df1e9105ab 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridCoverage.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/ConcatenatedGridCoverage.java
@@ -18,7 +18,6 @@ package org.apache.sis.storage.aggregate;
 
 import java.util.List;
 import java.util.ArrayList;
-import java.util.logging.Logger;
 import java.awt.image.RenderedImage;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.coverage.SampleDimension;
@@ -30,11 +29,12 @@ import org.apache.sis.coverage.grid.DisjointExtentException;
 import org.apache.sis.storage.GridCoverageResource;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.internal.storage.Resources;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.collection.Cache;
 import org.apache.sis.util.logging.Logging;
 
+import static org.apache.sis.internal.coverage.j2d.ImageUtilities.LOGGER;
+
 // Branch-dependent imports
 import org.opengis.coverage.CannotEvaluateException;
 
@@ -44,7 +44,7 @@ import org.opengis.coverage.CannotEvaluateException;
  * All components must have the same "grid to CRS" transform, except for a translation term.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.3
  */
 final class ConcatenatedGridCoverage extends GridCoverage {
@@ -334,8 +334,7 @@ final class ConcatenatedGridCoverage extends GridCoverage {
             try {
                 final RenderedImage image = coverage.render(locator.toSliceExtent(extent, index));
                 if (failure != null) {
-                    Logging.ignorableException(Logger.getLogger(Modules.STORAGE),
-                            ConcatenatedGridCoverage.class, "render", failure);
+                    Logging.ignorableException(LOGGER, ConcatenatedGridCoverage.class, "render", failure);
                 }
                 return image;
             } catch (DisjointExtentException e) {
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/package-info.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/package-info.java
index ad649537df..6ae0ad3b18 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/package-info.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/package-info.java
@@ -22,7 +22,7 @@
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.3
  */
 package org.apache.sis.storage.aggregate;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
index 00fa6a4a84..132133dcb2 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
@@ -36,7 +36,6 @@ import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.collection.Containers;
-import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.storage.Resources;
 import org.apache.sis.internal.storage.StoreResource;
 import org.apache.sis.internal.storage.StoreUtilities;
@@ -395,7 +394,7 @@ public class StoreListeners implements Localized {
      *   <li>the {@code LogRecord} does not {@linkplain LogRecord#getLoggerName() specify a logger}.</li>
      * </ul>
      *
-     * @return the logger where to send the warnings when there are no other destinations.
+     * @return the logger where to send the warnings when there is no other destination.
      *
      * @see DataStoreProvider#getLogger()
      *
@@ -599,7 +598,7 @@ public class StoreListeners implements Localized {
      * @param  error   the exception that occurred.
      */
     static void canNotNotify(final String method, final ExecutionException error) {
-        Logging.unexpectedException(Logger.getLogger(Modules.STORAGE), StoreListeners.class, method, error);
+        Logging.unexpectedException(StoreUtilities.LOGGER, StoreListeners.class, method, error);
     }
 
     /**
diff --git a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
index 1742924c78..c542d88bc9 100644
--- a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
+++ b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.storage.gpx;
 
 import java.util.Map;
+import java.util.logging.Logger;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import org.apache.sis.storage.DataStore;
@@ -49,6 +50,13 @@ public final class StoreProvider extends StaxDataStoreProvider {
      */
     public static final String NAME = "GPX";
 
+    /**
+     * The logger used by GPX stores.
+     *
+     * @see #getLogger()
+     */
+    private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.gpx");
+
     /**
      * The "1.0" version.
      */
@@ -110,4 +118,12 @@ public final class StoreProvider extends StaxDataStoreProvider {
     protected JAXBContext getJAXBContext() throws JAXBException {
         return JAXBContext.newInstance(Metadata.class);
     }
+
+    /**
+     * {@return the logger used by GPX stores}.
+     */
+    @Override
+    public Logger getLogger() {
+        return LOGGER;
+    }
 }