Add SLF4J logging support for Appium local service#1014
Add SLF4J logging support for Appium local service#1014SrinivasanTarget merged 13 commits intoappium:masterappium/java-client:masterfrom alexander-poulikakos:appium-local-service-loggingalexander-poulikakos/java-client:appium-local-service-loggingCopy head branch name to clipboard
Conversation
|
Please adjust indentation in all source files |
| */ | ||
| public void enableDefaultSlf4jLoggingOfOutputData() { | ||
| addSlf4jLogMessageConsumer((logMessage, ctx) -> { | ||
| if (ctx.level().equals(DEBUG)) { |
There was a problem hiding this comment.
This mapping is not sufficient, since Appium server uses more levels, for example warn and error
There was a problem hiding this comment.
Will add the other levels as well.
There was a problem hiding this comment.
Hmm, I have never seen an actual log message on either warn/error level. Do you know if they follow same format as debug? i.e. log message is prefixed with log level. Info level tag is not added in log message.
There was a problem hiding this comment.
I was just able to trigger a WARNmessage, but there is no log level indication in the log message it self. So will ignore warn and error levels for now.
Example
[Appium] Deprecated server args:
[Appium] --device-name => --default-capabilities '{"deviceName":"someName"}'
According to this, the above log message is at WARNlevel:
https://github.com/appium/appium/blob/7a00b3f875991ba1d95359ed53a3eda47911f64b/lib/main.js#L44
There was a problem hiding this comment.
the actual level is added there if logging timestamp is enabled:
2018-08-31 08:17:13:813 - info: [debug] [JSONWP Proxy] Got response with status 200: {"value":{"using":"class chain","value":"**/XCUIElementTypeCollectionView[`name == 'add_participants.list'`]/XCUIElementTypeCell[$name == 'user_cell.name' AND value == 'qrj7pcz5'$]","description":"unable to find an element"},"sessionId":"A4FBAD14-ED57-46D4-9407-B91C76BCB415","status":7}
2018-08-31 08:17:13:814 - info: [debug] [MJSONWP] Matched JSONWP error code 7 to NoSuchElementError
2018-08-31 08:17:13:815 - error: [W3C] Encountered internal error running command: NoSuchElementError: An element could not be located on the page using the given search parameters.
2018-08-31 08:17:13:815 - error: [W3C] at XCUITestDriver.callee$0$0$ (/usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver/lib/commands/find.js:130:13)
|
|
||
| static Slf4jLogMessageContext parseSlf4jContextFromLogMessage(String logMessage) { | ||
| Matcher m = LOGGER_CONTEXT_PATTERN.matcher(logMessage); | ||
| String loggerName = "appium.service"; |
There was a problem hiding this comment.
This should be in the constant
There was a problem hiding this comment.
I'm not following you on this. What should be in the constant? Which constant?
There was a problem hiding this comment.
private static final String LOGGER_NAME
| * @return {@link Logger} instance associated with this context. | ||
| * | ||
| */ | ||
| public Logger logger() { |
There was a problem hiding this comment.
java getters usually start with get
There was a problem hiding this comment.
will fix that
|
thanks for comments! What should I adjust indentation to? it seems to match the rest of the code lines. |
|
@mykola-mokhnach Can you please give more context regarding you comment |
|
@mykola-mokhnach How many spaces should it be per indentation? |
|
4 spaces |
|
@mykola-mokhnach regarding loglevel Anything else that I have missed? |
| */ | ||
| public void enableDefaultSlf4jLoggingOfOutputData() { | ||
| addSlf4jLogMessageConsumer((logMessage, ctx) -> { | ||
| if (ctx.getLevel().equals(DEBUG)) { |
There was a problem hiding this comment.
this is anyway not very accurate, since this [debug] prefix is also not always added to debug logs
There was a problem hiding this comment.
@mykola-mokhnach So what do you sugests instead? Should all be logged at INFO level? As it is now log messages with [debug] prefix is logged at DEBUG level. That is better than nothing if you ask me.
| }); | ||
| } | ||
|
|
||
| static Slf4jLogMessageContext parseSlf4jContextFromLogMessage(String logMessage) { |
There was a problem hiding this comment.
codacy does not like package-level visibility. Please add public
There was a problem hiding this comment.
@mykola-mokhnach There is a big difference between public and package private. Making it public will make it part of the public API, which is not desired in this case.
I don't think we should make an implementation detail public just because codacy says so, or?
| * | ||
| */ | ||
| public void addLogMessageConsumer(Consumer<String> consumer) { | ||
| addOutPutStream(new OutputStream() { |
There was a problem hiding this comment.
I'm not following this comment? addOutPutStream(...) is the name of an already existing method.
There was a problem hiding this comment.
There is a typo in this word
There was a problem hiding this comment.
@mykola-mokhnach
I'm still not following what this has to do with this PR?
As I said the addOutPutStream(...) method is already existing. Changing its name would be a breaking change.
There was a problem hiding this comment.
then yes, it is better to keep it as is if it was there
| assertLoggerContext(DEBUG, "appium.service.xcuitest", | ||
| "[debug] [XCUITest] Xcode version set to 'x.y.z' "); | ||
| assertLoggerContext(DEBUG, "appium.service.jsonwpproxy", | ||
| "[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:18218/status] with no body"); |
There was a problem hiding this comment.
How would you parse messages with timestamps like 2018-08-31 08:17:13:741 - info: [debug] [JSONWP Proxy] Matched '/element' to command name 'findElement' ?
There was a problem hiding this comment.
as mentioned in javadoc. this feature is not supported when --log-timestamp is enabled.
from javadoc:
NOTE2: it is required that {@code --log-timestamp} server flag is {@code false}.
There was a problem hiding this comment.
| List<String> log = new ArrayList<>(); | ||
| service = buildDefaultService(); | ||
| service.clearOutPutStreams(); | ||
| service.addLogMessageConsumer(log::add); |
There was a problem hiding this comment.
should we also have a possibility to remove a consumer?
There was a problem hiding this comment.
Essentially a consumer in this case is an OutputStream (as added with addOutPutStream(...) method). So consumers can be removed with the clearOutPutStreams() method.
| * BiConsumer block to be executed when a log message is | ||
| * available. | ||
| */ | ||
| public void addSlf4jLogMessageConsumer( |
There was a problem hiding this comment.
I find it useful to return self instance from such methods, so one can chain them
There was a problem hiding this comment.
I agree it is nice to return self to chain method calls. But no other methods in this class does that, so I figured to follow same pattern as other methods. Would be strange if only this method returned self.
|
I just realized these methods does not do a null check of given arguments. Will fix that. |
|
Will this be merged? |


Change list
Add possibilty to enable server output data logging through SLF4J loggers. This allow server output data to be configured with your preferred logging frameworks (e.g. java.util.logging, logback, log4j).
Types of changes
Details
Normal use case:
By default log messages are:
INFOlevel, unless log message is pre-fixed by[debug]then logged atDEBUGlevel.Example of log messages:
"[ADB] Cannot read version codes of "is logged by logger:appium.service.adbat levelINFO"[debug] [XCUITest] Xcode version set to 'x.y.z' "is logged by loggerappium.service.xcuitestat levelDEBUGMore general purposes
These methods are provided for more general use cases: