Skip to content

Commit c7efeb4

Browse files
committed
[FAB-16871] Deprecate Logger interface
Signed-off-by: Matthew B. White <[email protected]> Change-Id: Ieba3fc7fea8753e3de0748b93eef13975eef66fc
1 parent a4938e8 commit c7efeb4

File tree

4 files changed

+299
-4
lines changed

4 files changed

+299
-4
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
package org.hyperledger.fabric;
7+
8+
import java.io.PrintWriter;
9+
import java.io.StringWriter;
10+
import java.util.function.Supplier;
11+
import java.util.logging.Level;
12+
import java.util.logging.LogManager;
13+
14+
/**
15+
* Logger class to use throughout the Contract Implementation
16+
*
17+
* Only available within the 1.4.3 release, this class was a helper class that wrapped
18+
* the standard java.util.logging.
19+
*
20+
* This being deprecated as it doesn't enough extra function and also
21+
* log calls made via this can loose their 'caller method info'
22+
*
23+
* For chaincode/contract implementations please use java.util.logging
24+
* or your own framework. All the Hyperledger Fabric code here is logged
25+
* in loggers with names starting org.hyperledger
26+
*
27+
* @deprecated
28+
*/
29+
public class Logger extends java.util.logging.Logger {
30+
31+
protected Logger(String name) {
32+
super(name, null);
33+
34+
// ensure that the parent logger is set
35+
this.setParent(java.util.logging.Logger.getLogger("org.hyperledger.fabric"));
36+
}
37+
38+
public static Logger getLogger(String name) {
39+
return new Logger(name);
40+
}
41+
42+
/**
43+
* @deprecated
44+
*/
45+
public void debug(Supplier<String> msgSupplier) {
46+
log(Level.FINEST, msgSupplier);
47+
}
48+
49+
/**
50+
* @deprecated
51+
*/
52+
public void debug(String msg) {
53+
log(Level.FINEST, msg);
54+
}
55+
56+
public static Logger getLogger(Class<?> class1) {
57+
// important to add the logger to the log manager
58+
Logger l = Logger.getLogger(class1.getName());
59+
LogManager.getLogManager().addLogger(l);
60+
return l;
61+
}
62+
63+
/**
64+
* @deprecated
65+
*/
66+
public void error(String message) {
67+
log(Level.SEVERE, message);
68+
}
69+
70+
/**
71+
* @deprecated
72+
*/
73+
public void error(Supplier<String> msgSupplier) {
74+
log(Level.SEVERE, msgSupplier);
75+
}
76+
77+
/**
78+
* @deprecated
79+
*/
80+
public String formatError(Throwable throwable) {
81+
if (throwable == null)
82+
return null;
83+
final StringWriter buffer = new StringWriter();
84+
buffer.append(throwable.getMessage());
85+
throwable.printStackTrace(new PrintWriter(buffer));
86+
87+
Throwable cause = throwable.getCause();
88+
if (cause != null) {
89+
buffer.append(".. caused by ..");
90+
buffer.append(this.formatError(cause));
91+
}
92+
93+
return buffer.toString();
94+
}
95+
96+
}

fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,91 @@
77

88
import java.io.PrintWriter;
99
import java.io.StringWriter;
10-
import java.util.logging.Logger;
10+
import java.util.ArrayList;
11+
import java.util.Collections;
12+
import java.util.logging.Level;
13+
import java.util.logging.LogManager;
1114

1215
/**
13-
* Logger class to use throughout the Contract Implementation
16+
* Assistance class to use when logging.
17+
*
18+
* For chaincode/contract implementations please use java.util.logging or your
19+
* own framework. All the Hyperledger Fabric code here is logged in loggers with
20+
* names starting org.hyperledger
1421
*
22+
* Control of this is via the environment variables
23+
* 'CORE_CHAINCODE_LOGGING_LEVEL' this takes a string that matches the following
24+
* Java.util.logging levels (case insensitive)
25+
*
26+
* CRITICAL, ERROR -> Level.SEVERE, WARNING -> Level.WARNING, INFO -> Level.INFO
27+
* NOTICE -> Level.CONFIG, DEBUG -> Level.FINEST
28+
*
1529
*/
1630
public class Logging {
1731

1832
public static final String PERFLOGGER = "org.hyperledger.Performance";
1933

34+
/**
35+
* Formats a Throwable to a string with details of all the causes as well
36+
*
37+
* @param throwable Exception
38+
* @return String formatted with all the details
39+
*/
2040
public static String formatError(final Throwable throwable) {
2141
if (throwable == null) {
2242
return null;
2343
}
2444
final StringWriter buffer = new StringWriter();
25-
buffer.append(throwable.getMessage());
45+
buffer.append(throwable.getMessage()).append(System.lineSeparator());
46+
2647
throwable.printStackTrace(new PrintWriter(buffer));
2748

2849
final Throwable cause = throwable.getCause();
2950
if (cause != null) {
30-
buffer.append(".. caused by ..");
51+
buffer.append(".. caused by ..").append(System.lineSeparator());
3152
buffer.append(Logging.formatError(cause));
3253
}
3354

3455
return buffer.toString();
3556

3657
}
58+
59+
/**
60+
* Sets the log level to the the
61+
*/
62+
public static void setLogLevel(String newLevel) {
63+
64+
Level l = mapLevel(newLevel);
65+
LogManager logManager = LogManager.getLogManager();
66+
// slightly cumbersome approach - but the loggers don't have a 'get children'
67+
// so find those that have the correct stem.
68+
final ArrayList<String> allLoggers = Collections.list(logManager.getLoggerNames());
69+
allLoggers.add("org.hyperledger");
70+
allLoggers.stream().filter(name -> name.startsWith("org.hyperledger")).map(name -> logManager.getLogger(name))
71+
.forEach(logger -> {
72+
if (logger != null) {
73+
logger.setLevel(l);
74+
}
75+
});
76+
}
77+
78+
private static Level mapLevel(final String level) {
79+
if (level != null) {
80+
switch (level.toUpperCase().trim()) {
81+
case "ERROR":
82+
case "CRITICAL":
83+
return Level.SEVERE;
84+
case "WARNING":
85+
return Level.WARNING;
86+
case "INFO":
87+
return Level.INFO;
88+
case "NOTICE":
89+
return Level.CONFIG;
90+
case "DEBUG":
91+
return Level.FINEST;
92+
}
93+
}
94+
return Level.INFO;
95+
}
96+
3797
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
package org.hyperledger.fabric;
7+
import static org.hamcrest.CoreMatchers.containsString;
8+
import static org.junit.Assert.assertEquals;
9+
import static org.junit.Assert.assertThat;
10+
11+
import java.lang.reflect.InvocationTargetException;
12+
import java.lang.reflect.Method;
13+
import java.util.logging.Level;
14+
import java.util.logging.LogManager;
15+
16+
import org.hamcrest.CoreMatchers;
17+
import org.junit.Rule;
18+
import org.junit.Test;
19+
import org.junit.rules.ExpectedException;
20+
import org.mockito.Mockito;
21+
22+
public class LoggerTest {
23+
@Rule
24+
public ExpectedException thrown = ExpectedException.none();
25+
26+
27+
@Test
28+
public void testFormatError() {
29+
Exception e1 = new Exception("Computer says no");
30+
Logger l = Logger.getLogger("acme.wibble");
31+
assertThat(l.formatError(e1), containsString("Computer says no"));
32+
33+
NullPointerException npe1 = new NullPointerException("Nothing here");
34+
npe1.initCause(e1);
35+
36+
assertThat(l.formatError(npe1), containsString("Computer says no"));
37+
assertThat(l.formatError(npe1), containsString("Nothing here"));
38+
39+
assertThat(l.formatError(null), CoreMatchers.nullValue());
40+
}
41+
42+
@Test
43+
public void testGetLogger() {
44+
Logger l = Logger.getLogger(this.getClass());
45+
l.error("It'll be fine");
46+
l.error(()-> "It'll be fine, honest");
47+
l.debug("Well maybe");
48+
l.debug(()->"Well no.");
49+
}
50+
51+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
package org.hyperledger.fabric;
7+
import static org.hamcrest.CoreMatchers.containsString;
8+
import static org.junit.Assert.assertEquals;
9+
import static org.junit.Assert.assertThat;
10+
11+
import java.lang.reflect.InvocationTargetException;
12+
import java.lang.reflect.Method;
13+
import java.util.logging.Level;
14+
import java.util.logging.LogManager;
15+
16+
import org.hamcrest.CoreMatchers;
17+
import org.junit.Rule;
18+
import org.junit.Test;
19+
import org.junit.rules.ExpectedException;
20+
import org.mockito.Mockito;
21+
22+
public class LoggingTest {
23+
@Rule
24+
public ExpectedException thrown = ExpectedException.none();
25+
26+
@Test
27+
public void testMapLevel() {
28+
29+
assertEquals("Error maps", Level.SEVERE, proxyMapLevel( "ERROR"));
30+
assertEquals("Critical maps", Level.SEVERE, proxyMapLevel( "critical"));
31+
assertEquals("Warn maps", Level.WARNING, proxyMapLevel( "WARNING"));
32+
assertEquals("Info maps", Level.INFO, proxyMapLevel( "INFO"));
33+
assertEquals("Config maps", Level.CONFIG, proxyMapLevel( " notice"));
34+
assertEquals("Info maps", Level.INFO, proxyMapLevel( " info"));
35+
assertEquals("Debug maps", Level.FINEST, proxyMapLevel( "debug "));
36+
assertEquals("Info maps", Level.INFO, proxyMapLevel( "wibble "));
37+
assertEquals("Info maps", Level.INFO, proxyMapLevel(new Object[] {null}));
38+
}
39+
40+
public Object proxyMapLevel(Object... args) {
41+
42+
try {
43+
Method m = Logging.class.getDeclaredMethod("mapLevel", String.class);
44+
m.setAccessible(true);
45+
return m.invoke(null, args);
46+
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
47+
| InvocationTargetException e) {
48+
throw new RuntimeException(e);
49+
}
50+
51+
}
52+
53+
@Test
54+
public void testFormatError() {
55+
Exception e1 = new Exception("Computer says no");
56+
57+
assertThat(Logging.formatError(e1), containsString("Computer says no"));
58+
59+
NullPointerException npe1 = new NullPointerException("Nothing here");
60+
npe1.initCause(e1);
61+
62+
assertThat(Logging.formatError(npe1), containsString("Computer says no"));
63+
assertThat(Logging.formatError(npe1), containsString("Nothing here"));
64+
65+
assertThat(Logging.formatError(null), CoreMatchers.nullValue());
66+
}
67+
68+
@Test
69+
public void testSetLogLevel() {
70+
71+
java.util.logging.Logger l = java.util.logging.Logger.getLogger("org.hyperledger.fabric.test");
72+
java.util.logging.Logger another = java.util.logging.Logger.getLogger("acme.wibble");
73+
74+
Level anotherLevel = another.getLevel();
75+
Logging.setLogLevel("debug");
76+
assertThat(l.getLevel(),CoreMatchers.equalTo(Level.FINEST));
77+
assertThat(another.getLevel(),CoreMatchers.equalTo(anotherLevel));
78+
79+
Logging.setLogLevel("dsomethoig");
80+
assertThat(l.getLevel(),CoreMatchers.equalTo(Level.INFO));
81+
assertThat(another.getLevel(),CoreMatchers.equalTo(anotherLevel));
82+
83+
Logging.setLogLevel("ERROR");
84+
assertThat(l.getLevel(),CoreMatchers.equalTo(Level.SEVERE));
85+
assertThat(another.getLevel(),CoreMatchers.equalTo(anotherLevel));
86+
87+
}
88+
}

0 commit comments

Comments
 (0)