Skip to content

Commit

Permalink
Issue 25721 cli improve logging handling (#25858)
Browse files Browse the repository at this point in the history
* #25721 Logging configurations in application.properties files have been updated to improve overall logging efficiency.

* #25721 Logging configurations in application.properties files have been updated to improve overall logging efficiency.

* #25721 Logging configurations in application.properties files have been updated to improve overall logging efficiency.

* #25721 Logging configurations in application.properties files have been updated to improve overall logging efficiency.

* #25721 Add logging for executed commands

A new class, `LoggingExecutionStrategy`, has been added to the project. This class implements `IExecutionStrategy` with the added functionality to log the command being executed. It is used in `EntryCommand` class to wrap the existing execution strategy, allowing us to log the commands entered by users in the command-line interface. This helps in debugging by providing a clearer picture of the sequence of commands executed.

* #25721 Updating documentation
  • Loading branch information
jgambarios committed Aug 24, 2023
1 parent e689dc0 commit 2cdfd50
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 59 deletions.
60 changes: 47 additions & 13 deletions tools/dotcms-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ making sure that dependencies have been installed first
./mvnw clean install
```

To run cli.
Skipping tests

```shell script
# from top level to build all
./mvnw clean install -Dmaven.test.skip=true
```

### To run cli.

You might use [quarkus cli](https://es.quarkus.io/guides/cli-tooling) and [maven](https://maven.apache.org/install.html)

Expand All @@ -21,9 +28,7 @@ To run example API in dev mode
```shell script
# from top level to build all
cd cli
# command is same as the following to run the quarkus build plugin
# ../mvnw quarkus:dev
quarkus dev
./mvnw quarkus:dev
```
NOTE: To reduce duplication in the multi-module project mvnw is not included in each submodule.
The quarkus command finds the executable
Expand Down Expand Up @@ -74,12 +79,12 @@ https://picocli.info/

The creation of individual subcommands becomes easy with picocli, the current app demonstrates
some examples of what we can do.
####LoginCommand

#### LoginCommand
Shows example of getting a token from demo.cms.com and storing it in users personal secure storage
####StatusCommand
Checks the token status against the server and returns current user object.

#### StatusCommand
Checks the token status against the server and returns current user object.

## Docker
Checkout this link with a good description of the containerization and docker build options
Expand All @@ -96,12 +101,8 @@ https://quarkus.io/guides/config-reference

https://quarkus.io/get-started/



---



This project uses Quarkus, the Supersonic Subatomic Java Framework.

If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ .
Expand All @@ -110,7 +111,7 @@ If you want to learn more about Quarkus, please visit its website: https://quark

You can run your application in dev mode that enables live coding using:
```shell script
./mvnw compile quarkus:dev
./mvnw quarkus:dev
```

> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
Expand All @@ -131,6 +132,12 @@ If you want to build an _über-jar_, execute the following command:
./mvnw package -Dquarkus.package.type=uber-jar
```

Skipping tests

```shell script
./mvnw package -Dquarkus.package.type=uber-jar -Dmaven.test.skip=true
```

The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.

## Creating a native executable
Expand All @@ -145,6 +152,12 @@ Or, if you don't have GraalVM installed, you can run the native executable build
./mvnw package -Pnative -Dquarkus.native.container-build=true
```

Skipping tests

```shell script
./mvnw package -Pnative -Dquarkus.native.container-build=true -Dmaven.test.skip=true
```

You can then execute your native executable with: `./target/code-with-quarkus-1.0.0-SNAPSHOT-runner`

If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.
Expand All @@ -156,3 +169,24 @@ If you want to learn more about building native executables, please consult http
Easily start your Reactive RESTful Web Services

[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)

## Logging

When running the CLI, a **_dotcms-cli.log_** file will be created at the directory where the CLI
executable is run from.

#### File log level

To increase the file log level to _DEBUG_ when running in dev mode use the following command

```shell
./mvnw quarkus:dev -Dquarkus.log.file.level=DEBUG
```

#### Console log level

To increase the console log level to _DEBUG_ when running in dev mode use the following command

```shell
./mvnw quarkus:dev -Dquarkus.log.handler.console.\"DOTCMS_CONSOLE\".level=DEBUG
```
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,16 @@ Workspace workspace(final Path path) {
Optional<Path> findProjectRoot(Path currentPath) {

if (Files.exists(currentPath.resolve(DOT_WORKSPACE_YML))) {
logger.debug("Found workspace at: " + currentPath.toAbsolutePath());
logger.info("Found workspace at: " + currentPath.toAbsolutePath());
return Optional.of(currentPath);
} else {
Path parent;
Path workingPath = currentPath.toAbsolutePath();
logger.debug("looking up workspace, current path is : " + workingPath + " and parent is " + workingPath.getParent());
logger.info("looking up workspace, current path is : " + workingPath + " and parent is "
+ workingPath.getParent());
while ((parent = workingPath.getParent()) != null) {
if (Files.exists(parent.resolve(DOT_WORKSPACE_YML))) {
logger.debug("Found workspace at: " + currentPath.toAbsolutePath());
logger.info("Found workspace at: " + currentPath.toAbsolutePath());
return Optional.of(parent);
}
workingPath = parent;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
#quarkus.log.level=INFO
quarkus.log.level=ERROR
quarkus.log.category."com.dotcms".level=ERROR
%test.quarkus.log.category."com.dotcms".level=DEBUG
quarkus.log.syslog.level=ERROR
quarkus.log.console.level=FATAL
quarkus.log.category."com.dotcms".level=TRACE
# --
# Log file configuration
# --
quarkus.log.file.enable=true
# To override the level: ./mvnw quarkus:dev -Dquarkus.log.file.level=DEBUG
# For debug change this level to DEBUG
quarkus.log.file.level=INFO
quarkus.log.file.path=dotcms-cli.log
quarkus.log.file.rotation.max-file-size=10M
quarkus.log.file.rotation.max-backup-index=5
quarkus.log.file.rotation.rotate-on-boot=false
#quarkus.log.file.async=true
# --
# DOTCMS_CONSOLE handler is a console handler that only reports events up-to FATAL
# --
quarkus.log.handler.console."DOTCMS_CONSOLE".enable=true
# To override the level: ./mvnw quarkus:dev -Dquarkus.log.handler.console.\"DOTCMS_CONSOLE\".level=DEBUG
# For debug change this level to DEBUG
quarkus.log.handler.console."DOTCMS_CONSOLE".level=FATAL
%test.quarkus.log.handler.console."DOTCMS_CONSOLE".level=DEBUG
quarkus.log.category."com.dotcms".handlers=DOTCMS_CONSOLE

quarkus.banner.enabled=false
quarkus.http.port=9000

Expand Down
5 changes: 0 additions & 5 deletions tools/dotcms-cli/cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>

<dependency>
<groupId>com.starxg</groupId>
<artifactId>java-keytar</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void pull(OutputOptionMixin output, final AssetVersionsView assetInfo,

} catch (InterruptedException | ExecutionException e) {
var errorMessage = String.format("Error occurred while pulling asset: [%s].", e.getMessage());
logger.debug(errorMessage, e);
logger.error(errorMessage, e);
throw new RuntimeException(errorMessage, e);
} catch (Exception e) {// Fail fast

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void pull(OutputOptionMixin output, final TreeNode tree, final File desti

} catch (InterruptedException | ExecutionException e) {
var errorMessage = String.format("Error occurred while pulling assets: [%s].", e.getMessage());
logger.debug(errorMessage, e);
logger.error(errorMessage, e);
throw new RuntimeException(errorMessage, e);
} catch (Exception e) {// Fail fast

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public void processTreeNodes(OutputOptionMixin output, final String workspace,
} catch (InterruptedException | ExecutionException e) {

var errorMessage = String.format("Error occurred while pushing contents: [%s].", e.getMessage());
logger.debug(errorMessage, e);
logger.error(errorMessage, e);
throw new RuntimeException(errorMessage, e);
} catch (Exception e) {// Fail fast

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public Triple<List<Exception>, AssetsUtils.LocalPathStructure, TreeNode> travers

localPathStructure.setLanguageExists(false);

// Site doesn't exist on remote server
// Language doesn't exist on remote server
logger.debug(String.format("Language [%s] doesn't exist on remote server.", localPathStructure.language()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public AssetView push(final String workspace, final String status, final String
var response = assetAPI.push(uploadForm);
return response.entity();
} catch (IOException e) {
logger.debug(String.format("Error pushing asset %s", localAssetPath), e);
logger.error(String.format("Error pushing asset %s", localAssetPath), e);
throw new IllegalStateException(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private TreeNode gatherSyncInformation(File workspaceFile, File folderOrFile,
checkAssetsToPush(workspaceFile, live, lang, parentFolderAssetVersionsViewBuilder, files, remoteFolder);
} catch (Exception e) {
var message = String.format("Error processing folder [%s]", folderOrFile.getAbsolutePath());
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
}

Expand Down Expand Up @@ -236,7 +236,7 @@ private TreeNode gatherSyncInformation(File workspaceFile, File folderOrFile,
}
} catch (Exception e) {
var message = String.format("Error processing file [%s]", folderOrFile.getAbsolutePath());
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private void createFolderInFileSystem(final String destination, final FolderView
}
} catch (Exception e) {
var message = String.format("Error creating folder [%s] to [%s]", remoteFolderURL, folderPath);
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
}
}
Expand Down Expand Up @@ -210,7 +210,7 @@ private void createFileInFileSystem(final String destination, final FolderView f
}
} catch (Exception e) {
var message = String.format("Error pulling file [%s] to [%s]", remoteAssetURL, assetFilePath);
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
} finally {
// File processed, updating the progress bar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private void processFolder(final FolderView folder) {
if (!this.isRetry || !(e instanceof NotFoundException)) {

var message = String.format("Error deleting folder [%s]", folder.path());
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
}

Expand Down Expand Up @@ -191,6 +191,7 @@ private void processFolder(final FolderView folder) {

// If we are trying to create a site that already exist we could ignore the error on retries
if (!this.isRetry || !alreadyExist) {
logger.error(message, e);
throw new SiteCreationException(message, e);
}
} else {
Expand All @@ -200,6 +201,7 @@ private void processFolder(final FolderView folder) {

// If we are trying to create a folder that already exist we could ignore the error on retries
if (!this.isRetry || !alreadyExist) {
logger.error(message, e);
throw new TraversalTaskException(message, e);
}
}
Expand Down Expand Up @@ -242,7 +244,7 @@ private void processAsset(final FolderView folder, final AssetView asset) {
if (!this.isRetry || !(e instanceof NotFoundException)) {

var message = String.format("Error deleting asset [%s%s]", folder.path(), asset.name());
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
}

Expand All @@ -266,7 +268,7 @@ private void processAsset(final FolderView folder, final AssetView asset) {
// If we are trying to push an asset that already exist we could ignore the error on retries
if (!this.isRetry || !alreadyExist) {
var message = String.format("Error pushing asset [%s%s]", folder.path(), asset.name());
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ private FolderView retrieveFolderInformation(final String siteName, final String
return this.filter.apply(foundFolder);
} catch (Exception e) {
var message = String.format("Error retrieving folder information [%s]", folderPath);
logger.debug(message, e);
logger.error(message, e);
throw new TraversalTaskException(message, e);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.dotcms.cli.command;

import com.dotcms.cli.command.contenttype.*;
import com.dotcms.cli.command.contenttype.ContentTypeCommand;
import com.dotcms.cli.command.files.FilesCommand;
import com.dotcms.cli.command.language.LanguageCommand;
import com.dotcms.cli.command.site.*;
import com.dotcms.cli.command.site.SiteCommand;
import com.dotcms.cli.common.LoggingExecutionStrategy;
import com.dotcms.cli.common.OutputOptionMixin;
import io.quarkus.picocli.runtime.PicocliCommandLineFactory;
import io.quarkus.picocli.runtime.annotations.TopCommand;
Expand Down Expand Up @@ -55,6 +56,8 @@ class CustomConfiguration {
CommandLine customCommandLine( final PicocliCommandLineFactory factory) {
return factory.create()
.setCaseInsensitiveEnumValuesAllowed(true)
.setExecutionStrategy(
new LoggingExecutionStrategy(new CommandLine.RunLast()))
.setExecutionExceptionHandler((ex, commandLine, parseResult) -> {
final Object object = commandLine.getCommand();
if (object instanceof DotCommand) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.dotcms.cli.common;

import picocli.CommandLine;
import picocli.CommandLine.ExecutionException;
import picocli.CommandLine.IExecutionStrategy;
import picocli.CommandLine.ParameterException;

/**
* This class implements the execution strategy interface, with the added functionality of logging
* the command being executed.
*/
public class LoggingExecutionStrategy implements IExecutionStrategy {

private static final java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger(
LoggingExecutionStrategy.class.getName());
private final IExecutionStrategy underlyingStrategy;

/**
* Constructs a new instance of LoggingExecutionStrategy with the provided underlying strategy.
*
* @param underlyingStrategy the underlying strategy to use for execution
*/
public LoggingExecutionStrategy(IExecutionStrategy underlyingStrategy) {
this.underlyingStrategy = underlyingStrategy;
}

/**
* Executes the command specified in the parse result, while logging the executed command.
*
* @param parseResult the parse result from which to select one or more CommandSpec instances to
* execute
* @return the exit code of the executed command
* @throws ExecutionException if an exception occurs during command execution
* @throws ParameterException if there is an error with the command parameters
*/
@Override
public int execute(CommandLine.ParseResult parseResult)
throws ExecutionException, ParameterException {

if (!parseResult.originalArgs().isEmpty()) {
String commandLineString = String.join(" ", parseResult.originalArgs());
LOGGER.info("Executing command: " + commandLineString);
}

return underlyingStrategy.execute(parseResult);
}
}
Loading

0 comments on commit 2cdfd50

Please sign in to comment.