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

IGNITE-23472 Fix JavaLogger #11615

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Conversation

chesnokoff
Copy link
Contributor

@chesnokoff chesnokoff commented Oct 23, 2024

JavaLogger.configure method is invoked only once for all instances and it configures cfg field which was not static. Because of that only one instance had correct value and other instances had cfg with null value

Thank you for submitting the pull request to the Apache Ignite.

In order to streamline the review of the contribution
we ask you to ensure the following steps have been taken:

The Contribution Checklist

  • There is a single JIRA ticket related to the pull request.
  • The web-link to the pull request is attached to the JIRA ticket.
  • The JIRA ticket has the Patch Available state.
  • The pull request body describes changes that have been made.
    The description explains WHAT and WHY was made instead of HOW.
  • The pull request title is treated as the final commit message.
    The following pattern must be used: IGNITE-XXXX Change summary where XXXX - number of JIRA issue.
  • A reviewer has been mentioned through the JIRA comments
    (see the Maintainers list)
  • The pull request has been checked by the Teamcity Bot and
    the green visa attached to the JIRA ticket (see TC.Bot: Check PR)

Notes

If you need any help, please email [email protected] or ask anу advice on http://asf.slack.com #ignite channel.

@chesnokoff chesnokoff force-pushed the ignite-23472 branch 2 times, most recently from 47549cd to 64a31fb Compare November 1, 2024 09:46
IgniteLogger log2 = log1.getLogger(getClass());

assertTrue(log1.toString().contains("JavaLogger"));
assertTrue(log1.toString().contains(JavaLogger.DFLT_CONFIG_PATH));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert failed and was fixed by this(true) change in default constructor


assertTrue(logContent.contains("[INFO] Accepted info"));
assertFalse(logContent.contains("[DEBUG] Ignored debug"));
assertTrue(logContent.contains("[DEBUG] Accepted debug"));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert fails

log.info("Accepted info");
log.debug("Ignored debug");

log = logSupplier.get(debugCfgFile);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configuration of log is still infoCfgFile because cfg field is inited only once. That's why "Accepted debug" won't be logged

/**
* Configure java.util.logging.config.file property
*/
private void setJavaLoggerConfig() throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method can be inlined

private void setJavaLoggerConfig() throws IOException {
File file = new File(U.getIgniteHome(), LOG_CONFIG_DEBUG);
System.setProperty("java.util.logging.config.file", file.getPath());
LogManager.getLogManager().readConfiguration();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose user shouldn't explicitly read configuration. It is invoked inside LogManager while user tries to log first message, isn't it?

Copy link
Contributor Author

@chesnokoff chesnokoff Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LogManager reads the property when Logger.getLogger method is called first time.
The problem is that it happens before System.setProperty

Firstly, it happens because JavaLoggerTest extends GridCommonAbstractTest which initialize IgniteUtils and IgniteUtils calls Logger.getLogger.

Secondly, U.getIgniteHome() also calls initialization of IgniteUtils and it calls Logger.getLogger again.

So Logger.getLogger is called before setProperty and that's why jul won't read this property without explicit configuration.

private static final Logger log = Logger.getLogger(IgniteUtils.class.getName());

@@ -194,7 +194,7 @@ public JavaLogger(boolean init) {
* @param impl Java Logging implementation to use.
*/
public JavaLogger(final Logger impl) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this constructor?



/**
* Check JavaLogger default constructor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sentences in comments and javadocs should end with a dot sign.

cfg.setGridLogger(log);
startGrid(cfg);

doSleep(2_000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use sleep for waiting any events. Use instead GridTestUtils#waitForCondition.

@Test
public void testGridLoggingWithCustomLogger() throws Exception {
AtomicBoolean hasLog = new AtomicBoolean(false);
Filter filter = record -> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use LogListener instead

Copy link
Contributor Author

@chesnokoff chesnokoff Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ListeningTestLogger did not have toString method implementation. That's why I've edited ListeningTestLogger

@chesnokoff chesnokoff force-pushed the ignite-23472 branch 2 times, most recently from 5f057ff to fc07c23 Compare November 8, 2024 13:06
@@ -84,4 +153,5 @@ public void testLogInitialize() throws Exception {
assert !log.fileName().contains("%");
assert log.fileName().contains("other-app");
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless change

@chesnokoff chesnokoff force-pushed the ignite-23472 branch 4 times, most recently from 9e7fa81 to c4ac02e Compare November 9, 2024 16:30
public void testDefaultConstructorWithProperty() throws Exception {
File file = new File(U.getIgniteHome(), LOG_CONFIG_DEBUG);
System.setProperty("java.util.logging.config.file", file.getPath());
// Call readConfiguration explicitly because Logger.getLogger was already called during IgniteUtils initialization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should be ended with a dot sign.

assertTrue(log2.toString().contains(LOG_CONFIG_DEBUG));
assertTrue(log1.isDebugEnabled());

System.clearProperty("java.util.logging.config.file");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will not call in case of an assertion error.

cfg.setGridLogger(log);
startGrid(cfg);

assertTrue(GridTestUtils.waitForCondition(lsn::check, 2_000));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you wait for the check in background?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the program would log after the execution of startGrid. However, I've checked it, and the message is actually logged before the execution of startGrid completes.

/** {@inheritDoc} */
@Override public IgniteLogger getLogger(Object ctgr) {
return new JavaLogger(ctgr == null
? Logger.getLogger("")
: Logger.getLogger(ctgr instanceof Class
? ((Class<?>)ctgr).getName()
: String.valueOf(ctgr)));
: String.valueOf(ctgr)), quiet, cfg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It starts invoking another constructor. Before your change there was a chain:

JavaLogger#getLogger(Object) -> new JavaLogger(Logger, configure=true)

After your change, in case root logger created as new JavaLogger(false) the underlying logger will use constructor with no configuration and it never been configured. And the constructor JavaLogger(Logger, boolean) is useless. Is it ok?

startGrid(cfg);

assertTrue(GridTestUtils.waitForCondition(lsn::check, 2_000));
stopAllGrids();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be replaced with

try(Ignite ign = startGrid(cfg) {
    ...
}

@@ -271,6 +271,23 @@ public GridTestLog4jLogger(final URL cfgUrl) throws IgniteCheckedException {
quiet = quiet0;
}

/**
* Creates new logger with given implementation.
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove useless blank line

File xml = GridTestUtils.resolveIgnitePath(LOG_PATH_TEST);

assert xml != null;
assert xml.exists();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the existence is already tested in GridTestUtils.resolveIgnitePath

Copy link
Contributor Author

@chesnokoff chesnokoff Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied this part of the code from Log4j2LoggerSelfTest. Now I've fixed it in both GridTestLog4jLoggerSelfTest and Log4j2LoggerSelfTest.


IgniteLogger log = new GridTestLog4jLogger(xml).getLogger(getClass());

System.out.println(log.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not sout anything in tests

Copy link
Contributor Author

@chesnokoff chesnokoff Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous answer about Log4j2LoggerSelfTest.

@chesnokoff chesnokoff force-pushed the ignite-23472 branch 3 times, most recently from 162f57c to 773eb80 Compare November 17, 2024 19:57
@chesnokoff chesnokoff force-pushed the ignite-23472 branch 2 times, most recently from 2886b29 to af6ab6f Compare November 25, 2024 09:14
IgniteLogger log2 = log1.getLogger(getClass());
assertTrue(log2.toString().contains("JavaLogger"));
assertTrue(log2.toString().contains(LOG_CONFIG_DEBUG));
assertTrue(log1.isDebugEnabled());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log2?


IgniteConfiguration cfg = getConfiguration(getTestIgniteInstanceName());
cfg.setGridLogger(log);
try (Ignite ign = startGrid(cfg)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a blank line before this line


IgniteConfiguration cfg = getConfiguration(getTestIgniteInstanceName());
cfg.setGridLogger(log);
try (Ignite ign = startGrid(cfg)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name ign -> ignore, to avoid a warning about unused variable in IDEA

assertTrue(log.toString().contains("GridTestLog4jLogger"));
assertTrue(log.toString().contains(xml.getPath()));

log.setApplicationAndNode(null, UUID.randomUUID());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need it?

public static void beforeTests() {
@Before
public void beforeTest() {
System.clearProperty("appId");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make GridTestLog4jLogger#APP_ID package private and use this variable

@chesnokoff chesnokoff force-pushed the ignite-23472 branch 4 times, most recently from 2b9847b to d51ef1c Compare November 26, 2024 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants