Repository: dita-ot/dita-ot
Issue: Build log should provide the name of the file where the issue was found

## Expected Behavior
When DITA OT encounters a `keyref ERROR [DOTJ046E]` and a `filter WARNING [DOTJ049W]`, it should provide the name of the file where the issue was found.

## Actual Behavior
The build log shows only the following messages, without providing the name of the file where the issue was found:

```
[keyref] [DOTJ046E][ERROR] Conkeyref="cloud/cloudPlatformFull" can not be resolved because it does not contain a key or the key is not defined. The build will use the conref attribute for fallback, if one exists.
```

```
[filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
```

## Possible Solution
Extend the build log to provide clear information on where the issue was found

## Copy of the error message, log file or stack trace
```
13:26:40      [keyref] [DOTJ046E][ERROR] Conkeyref="cloud/csBookTitle" can not be resolved because it does not contain a key or the key is not defined. The build will use the conref attribute for fallback, if one exists.
13:27:00      [keyref] [DOTJ046E][ERROR] Conkeyref="cloud/productNameSuffix" can not be resolved because it does not contain a key or the key is not defined. The build will use the conref attribute for fallback, if one exists.
13:27:00      [keyref] [DOTJ046E][ERROR] Conkeyref="cloud/productNameSuffix" can not be resolved because it does not contain a key or the key is not defined. The build will use the conref attribute for fallback, if one exists.
13:27:07      [keyref] [DOTJ046E][ERROR] Conkeyref="cloud/productNameSuffix" can not be resolved because it does not contain a key or the key is not defined. The build will use the conref attribute for fallback, if one exists.
13:27:07      [keyref] [DOTJ046E][ERROR] Conkeyref="cloud/productNameSuffix" can not be resolved because it does not contain a key or the key is not defined. The build will use the conref attribute for fallback, if one exists.
```

```
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the chunk attribute: select-branch to-content by-content
12:31:27      [filter] [DOTJ049W][WARN] The attribute value chunk="to-content" on element "chapter" does not comply with the specified subject scheme. According to the subject scheme map, the following
12:33:11      [filter] [DOTJ049W][WARN] The attribute value audience="release" on element "topichead" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the audience attribute: internal,external,earlyaccess,reviewer
```

## Environment

* DITA-OT version: 3.4.1
* Operating system and version: Docker image created from the `adoptopenjdk:11-jdk-hotspot` image
* How did you run DITA-OT? `dita` command
* Transformation type: Customized Oxygen Webhelp responsive


Changed files:
src/main/java/org/dita/dost/writer/ValidationFilter.java, src/main/java/org/dita/dost/reader/ConrefPushReader.java, src/main/java/org/dita/dost/writer/include/IncludeText.java, src/main/java/org/dita/dost/writer/ConkeyrefFilter.java, src/main/java/org/dita/dost/reader/KeydefFilter.java, src/main/java/org/dita/dost/reader/DitaValReader.java, src/main/java/org/dita/dost/reader/MergeMapParser.java, src/main/java/org/dita/dost/reader/CopyToReader.java

diff --git a/src/main/java/org/dita/dost/reader/ConrefPushReader.java b/src/main/java/org/dita/dost/reader/ConrefPushReader.java
index 12f37f7a7..ea19ba687 100644
--- a/src/main/java/org/dita/dost/reader/ConrefPushReader.java
+++ b/src/main/java/org/dita/dost/reader/ConrefPushReader.java
@@ -269,7 +269,7 @@ public final class ConrefPushReader extends AbstractXMLReader {
                 final String fragment = target.getFragment();
                 if (fragment == null) {
                     //if there is no '#' in target string, report error
-                    logger.error(MessageUtils.getMessage("DOTJ041E", target.toString()).toString());
+                    logger.error(MessageUtils.getMessage("DOTJ041E", target.toString()).setLocation(atts).toString());
                 } else {
                     String id;
                     //has element id
diff --git a/src/main/java/org/dita/dost/reader/CopyToReader.java b/src/main/java/org/dita/dost/reader/CopyToReader.java
index 1d4176775..752e5ee6b 100644
--- a/src/main/java/org/dita/dost/reader/CopyToReader.java
+++ b/src/main/java/org/dita/dost/reader/CopyToReader.java
@@ -162,7 +162,8 @@ public final class CopyToReader extends AbstractXMLFilter {
                     final URI copyToSourceAbs = copyToMap.get(targetAbs);
                     if (copyToSourceAbs != null) {
                         if (!sourceAbs.equals(copyToSourceAbs)) {
-                            logger.warn(MessageUtils.getMessage("DOTX065W", source.toString(), targetAbs.toString()).toString());
+                            logger.warn(MessageUtils.getMessage("DOTX065W", source.toString(), targetAbs.toString())
+                                    .setLocation(atts).toString());
                         }
                     } else if (atts.getValue(ATTRIBUTE_NAME_CHUNK) != null &&
                             atts.getValue(ATTRIBUTE_NAME_CHUNK).contains(CHUNK_TO_CONTENT)) {
diff --git a/src/main/java/org/dita/dost/reader/DitaValReader.java b/src/main/java/org/dita/dost/reader/DitaValReader.java
index f05ec2776..21d810971 100644
--- a/src/main/java/org/dita/dost/reader/DitaValReader.java
+++ b/src/main/java/org/dita/dost/reader/DitaValReader.java
@@ -179,7 +179,7 @@ public final class DitaValReader implements AbstractReader {
                 action = readFlag(elem);
                 break;
             default:
-                throw new IllegalArgumentException(MessageUtils.getMessage("DOTJ077F", attAction).toString());
+                throw new IllegalArgumentException(MessageUtils.getMessage("DOTJ077F", attAction).setLocation(elem).toString());
         }
         if (action != null) {
             final QName attName;
@@ -205,7 +205,7 @@ public final class DitaValReader implements AbstractReader {
                 }
                 if (attName != null && attName.equals(REV)
                         && !filterAttributes.isEmpty() && !filterAttributes.contains(REV)) {
-                    logger.warn(MessageUtils.getMessage("DOTJ074W").toString());
+                    logger.warn(MessageUtils.getMessage("DOTJ074W").setLocation((elem)).toString());
                     return;
                 }
             }
diff --git a/src/main/java/org/dita/dost/reader/KeydefFilter.java b/src/main/java/org/dita/dost/reader/KeydefFilter.java
index be8727746..eff88d0cc 100644
--- a/src/main/java/org/dita/dost/reader/KeydefFilter.java
+++ b/src/main/java/org/dita/dost/reader/KeydefFilter.java
@@ -144,7 +144,7 @@ public final class KeydefFilter extends AbstractXMLFilter {
                         keysDefMap.put(key, new KeyDef(key, null, null, null, null, null));
                     }
                 } else {
-                    logger.info(MessageUtils.getMessage("DOTJ045I", key).toString());
+                    logger.info(MessageUtils.getMessage("DOTJ045I", key).setLocation(atts).toString());
                 }
             }
         }
diff --git a/src/main/java/org/dita/dost/reader/MergeMapParser.java b/src/main/java/org/dita/dost/reader/MergeMapParser.java
index 3c9b0553d..aae040e70 100644
--- a/src/main/java/org/dita/dost/reader/MergeMapParser.java
+++ b/src/main/java/org/dita/dost/reader/MergeMapParser.java
@@ -227,7 +227,9 @@ public final class MergeMapParser extends XMLFilterImpl {
                             XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_FIRST_TOPIC_ID, firstTopicId.toString());
                         } else {
                             final URI fileName = URLUtils.toDirURI(dirPath).resolve(attValue);
-                            logger.error(MessageUtils.getMessage("DOTX008E", fileName.toString()).toString());
+                            logger.error(MessageUtils.getMessage("DOTX008E", fileName.toString())
+                                    .setLocation(attributes)
+                                    .toString());
                         }
                     }
                     }
diff --git a/src/main/java/org/dita/dost/writer/ConkeyrefFilter.java b/src/main/java/org/dita/dost/writer/ConkeyrefFilter.java
index ffe86137c..0d67b5696 100644
--- a/src/main/java/org/dita/dost/writer/ConkeyrefFilter.java
+++ b/src/main/java/org/dita/dost/writer/ConkeyrefFilter.java
@@ -75,10 +75,10 @@ public final class ConkeyrefFilter extends AbstractXMLFilter {
                     }
                     XMLUtils.addOrSetAttribute(resAtts, ATTRIBUTE_NAME_CONREF, target.toString());
                 } else {
-                    logger.warn(MessageUtils.getMessage("DOTJ060W", key, conkeyref).toString());
+                    logger.warn(MessageUtils.getMessage("DOTJ060W", key, conkeyref).setLocation(atts).toString());
                 }
             } else {
-                logger.error(MessageUtils.getMessage("DOTJ046E", conkeyref).toString());
+                logger.error(MessageUtils.getMessage("DOTJ046E", conkeyref).setLocation(atts).toString());
             }
         }
         getContentHandler().startElement(uri, localName, name, resAtts != null ? resAtts : atts);
diff --git a/src/main/java/org/dita/dost/writer/ValidationFilter.java b/src/main/java/org/dita/dost/writer/ValidationFilter.java
index 617f54905..cb3f06f9c 100644
--- a/src/main/java/org/dita/dost/writer/ValidationFilter.java
+++ b/src/main/java/org/dita/dost/writer/ValidationFilter.java
@@ -304,7 +304,9 @@ public final class ValidationFilter extends AbstractXMLFilter {
                     for (final String s : keylist) {
                         if (!StringUtils.isEmptyString(s) && !valueSet.contains(s)) {
                             logger.warn(MessageUtils.getMessage("DOTJ049W",
-                                    attrName.toString(), qName, attrValue, StringUtils.join(valueSet, COMMA)).toString());
+                                            attrName.toString(), qName, attrValue, StringUtils.join(valueSet, COMMA))
+                                    .setLocation(atts)
+                                    .toString());
                         }
                     }
                 }
diff --git a/src/main/java/org/dita/dost/writer/include/IncludeText.java b/src/main/java/org/dita/dost/writer/include/IncludeText.java
index 79690145b..e4cff074d 100644
--- a/src/main/java/org/dita/dost/writer/include/IncludeText.java
+++ b/src/main/java/org/dita/dost/writer/include/IncludeText.java
@@ -42,7 +42,7 @@ final class IncludeText {
 
     boolean include(final Attributes atts) {
         final URI hrefValue = toURI(atts.getValue(ATTRIBUTE_NAME_HREF));
-        final Charset charset = getCharset(atts.getValue(ATTRIBUTE_NAME_FORMAT), atts.getValue(ATTRIBUTE_NAME_ENCODING));
+        final Charset charset = getCharset(atts);
         final Range range = getRange(hrefValue);
         final File codeFile = getFile(hrefValue);
         if (codeFile != null) {
@@ -125,11 +125,12 @@ final class IncludeText {
     /**
      * Get code file charset.
      *
-     * @param format   format attribute value, may be {@code null}
-     * @param encoding encoding attribute balue, may be {@code null}
      * @return charset if set, otherwise default charset
      */
-    private Charset getCharset(final String format, final String encoding) {
+
+    private Charset getCharset(Attributes atts) {
+        final String format = atts.getValue(ATTRIBUTE_NAME_FORMAT);
+        final String encoding = atts.getValue(ATTRIBUTE_NAME_ENCODING);
         Charset c = null;
         try {
             if (encoding != null) {
@@ -141,7 +142,7 @@ final class IncludeText {
                 }
             }
         } catch (final RuntimeException e) {
-            logger.error(MessageUtils.getMessage("DOTJ052E", encoding).toString());
+            logger.error(MessageUtils.getMessage("DOTJ052E", encoding).setLocation(atts).toString());
         }
         if (c == null) {
             final String defaultCharset = Configuration.configuration.get("default.coderef-charset");