Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identifiers, names, refs, nightmare docs, logging hell level 999 #1285

Closed
robozb opened this issue Feb 23, 2023 · 4 comments
Closed

Identifiers, names, refs, nightmare docs, logging hell level 999 #1285

robozb opened this issue Feb 23, 2023 · 4 comments
Labels
documentation Pull requests or issues that affect documentation

Comments

@robozb
Copy link

robozb commented Feb 23, 2023

Why do you need both identifiers and names? Is one of them not enough to identify the appender at logger definition?

for example: appender.console.name = STDOUT

I know my english is terrible, but this is the most incomprehensible documentation I have ever read:

https://logging.apache.org/log4j/2.x/manual/configuration.html#Properties

It is full of ambiguous statements. Brain surgery is easier to learn than log4j documentation. It has more information than in the Bible. It is not easy to use at all compared to version 1, what worked really well! Unnecessarily overcomplicated.

@robozb robozb changed the title Identifiers, names, refs Identifiers, names, refs, nightmare docs Feb 23, 2023
@robozb robozb changed the title Identifiers, names, refs, nightmare docs Identifiers, names, refs, nightmare, logging hel level 999 Feb 23, 2023
@robozb robozb changed the title Identifiers, names, refs, nightmare, logging hel level 999 Identifiers, names, refs, nightmare, logging hell level 999 Feb 23, 2023
@robozb robozb changed the title Identifiers, names, refs, nightmare, logging hell level 999 Identifiers, names, refs, nightmare docs, logging hell level 999 Feb 23, 2023
@rgoers
Copy link
Member

rgoers commented Feb 23, 2023

The Log4j configuration is a tree structure organized as "Nodes" where a Node is nothing but a container of attributes and child Nodes. All the configuration dialects Log4j supports are converted into a Node tree. This works great for Yaml, JSON, and XML. Unfortunately, by their nature properties are not hierarchical. This means using properties is somewhat fitting a round peg in a square hole. For years Log4j didn't support properties due to this but we finally added it due to user's requests. We have made slight "improvements" over time at user's requests but in the end I really don't think it makes it any simpler.

As an example of how Log4j configuration works, a more complete form of your example above

appender.console.name = STDOUT
appender.console.type = Console
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n

appender.file.name = File
appender.file.type = File
appender.file.fileName = ${filename}
appender.file.bufferedIO = false
appender.file.layout.type = PatternLayout
appender.file.layout.pattern = %d %p %C{1.} [%t] %m%n

would correspond to:

XML

    <Console name="STDOUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
    <File name="File" fileName="${filename}" bufferedIO="false">
      <PatternLayout>
        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>  

JSON

        "appenders" : {
            "Console" : {
                "name" : "STDOUT",
                "PatternLayout" : {
                    "Pattern": "%m%n"
                }
            },
            "File" : {
                "name": "File",
                "fileName": "${filename}",
                "bufferedIO": false,
                "PatternLayout" : {
                    "Pattern": "%d %p %C{1.} [%t] %m%n"
                }
            }
          }

YAML

  appenders:
    Console:
      name: STDOUT
      PatternLayout:
        Pattern: "%m%n"
    File:
      name: File
      fileName: ${filename}
      bufferedIO: false
      PatternLayout:
        Pattern: "%d %p %C{1.} [%t] %m%n"

In the properties format the first identifier lets Log4j know that this is a child Appender under the Appenders node. The "console" and "file" are tokens that indicate all the properties with that token are grouped together. Finally, the final tokens represent the attributes of the appender with the exception of the "type", which indicates that it is a "Console" appender. Note that the Console appender also has a second token used for grouping; "layout". The type indicates it is a PattermLayout and the pattern is the attribute for that.

I should note that the way Log4j 1 handled configuration was completely different. Properties were the original and only format. XML was bolted on after the fact and was basically a different configuration system from using properties. In addition, Log4j 1.x didn't support the "type". It required every component have a class attribute with the fully qualified class name instead. So where you see a type in the properties configuration you would have replaced with a class token. Although in many examples the "type" and the "name" might have the same value the name used is entirely up to the user. So if your configuration has multiple File Appenders both would have a type of "File" but each would have a unique name.

I, for one, highly encourage users to use a different one of the other formats.

I should also add that anyone can write a new configuration factory. You can even replace the PropertiesConfigurationFactory with one of your own if you desire.

@robozb
Copy link
Author

robozb commented Feb 23, 2023

Dear @rgoers,

Thank you very much for your quick answer! You are really kind!

Best Regards: Bela

@ppkarwasz
Copy link
Contributor

@robozb,

The identifiers in the properties format are almost useless. One of the last attempts to make the properties format more digestible (#733 and related issues) proposed to use them as default appender names, but the feature never made it out to the main code.

Such a usage would be in line with what Log4j 1.x did, but is not coherent with other formats: most formats use the identifiers/keys/element names to indicate the plugin type. You can see it in Ralph's YAML example:

 appenders:
   Console:
     name: STDOUT
     PatternLayout:
       Pattern: "%m%n"
    File:
      name: FILE
      fileName: ${filename}
      bufferedIO: false
      PatternLayout:
        Pattern: "%d %p %C{1.} [%t] %m%n"

The keys Console, File and PatternLayout associated to YAML objects are used as default values for the missing type properties.

We could probably implement something similar in the properties format:

appender.Console.name = STDOUT
appender.Console.PatternLayout.pattern = "%m%n"

appender.File.name = FILE
appender.File.fileName = ${filename}
appender.File.bufferedIO = false
appender.File.PatternLayout.pattern = %d %p %C{1.} [%t] %m%n

However there isn't much to be done if multiple appenders of the same type are required. In the YAML format we currently support the following shorthand:

Appenders:
  File:
    - name: FILE1
      fileName: file1.log
    - name: FILE2
      fileName: file2.log

(i.e. for YAML arrays the default type is the key associated to the array). I don't think anything similar would be possible for the properties format.

@robozb
Copy link
Author

robozb commented Feb 23, 2023

Dear @ppkarwasz,

Thank you for the details!

Regards: Bela

@jvz jvz added question documentation Pull requests or issues that affect documentation labels Mar 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Pull requests or issues that affect documentation
Projects
None yet
Development

No branches or pull requests

4 participants