-
Language:
English
-
Language:
English
Open Liberty Runtime Guide
Build and deploy cloud native applications with Open Liberty
Abstract
Chapter 1. What is Open Liberty
Open Liberty is a lightweight Java runtime for building cloud-native applications and microservices.
With Open Liberty, it’s easy to add and remove modular features from the latest versions of Jakarta EE and Eclipse MicroProfile. This modular structure simplifies microservice development, enabling you to run Just enough Application Server to support the features that your application needs. Furthermore, with Open Liberty zero migration architecture, you can upgrade to the latest version with minimal impact to your current applications and configurations. Open Liberty is compatible with the Jakarta EE 8 Full Platform and Web Profile specifications and with MicroProfile 3.0. For more information, see the Open Liberty website. For the latest updates about Open Liberty features and capabilities, see the Open Liberty blog and Open Liberty docs.
Open Liberty is one of the Java runtimes available on OpenShift, and support is provided as part of a Red Hat subscription. Run Open Liberty on OpenShift to build and deploy cloud-native applications with the benefits of the OpenShift platform. For more information about using Open Liberty with OpenShift, see Deploying microservices to OpenShift.
1.1. Open Liberty Versioning
Traditional versioning follows some variation of the major.minor.micro scheme, where significant new function is only delivered in a major release. These major releases contain key new capabilities, but they also make behavior changes that require application migration and significant regression testing to adopt. As a result, multiple major versions are supported at any one time. The modular feature architecture of Open Liberty, in combination with zero migration, allows the delivery of new function incrementally, without following a major.minor.micro versioning scheme.
Instead of major releases, each Open Liberty release is considered a micro, or patch release. These patch releases follow a yy.0.0.nn version scheme. The first two digits indicate the year of release and the last two digits indicate the number of the release within that year. Even though the first set of digits changes each year, the releases are of equal standing. For example, the difference between 20.0.0.1 (the first release of 2020) and 19.0.0.12 (the last release of 2019) is identical to the difference between 19.0.0.10 and 19.0.0.11.
The lack of major release streams is unusual for server runtimes, but is common for desktop and mobile applications. Some publication systems expect software to have a major version. As a result, in cases where a major version is needed, the year of publication is used as a stand-in. For example, Open Liberty documentation that is published for this guide in 2019 uses the year 2019 as the version number. However, this documentation is as applicable to releases in 2020 as it is to releases in 2019.
Chapter 2. Packaging and Deploying applications
You can package everything you need to run your application in a container image and use containers to deploy it in different environments. When you run Open Liberty applications on OpenShift, you combine the most flexible server runtime available to Java developers with a streamlined DevOps process and an intuitive development pipeline.
For more information, see Deploying microservices to OpenShift.
To learn how to containerize and run your microservices with Open Liberty, see Containerizing microservices.
Open Liberty supports all MicroProfile and Java EE APIs and deploys to every major cloud platform. To get started with Open Liberty, learn how to to run and update a simple REST microservice with Packaging and deploying applications.
Additional resources
Chapter 3. Feature overview
Features are the discrete units of functionality by which you control the pieces of the runtime environment that are loaded into a particular server. By adding or removing features from your server configuration, you can control what functions the server can perform. Features provide the programming models and services that applications require. You can specify any feature in the server configuration files. Some features include other features within them, and the same feature might be included in one or more other features.
When the server is started, the JVM is launched and control is passed to the Open Liberty kernel. The configuration is loaded as described in the Server configuration overview. When the configuration is parsed, the feature manager gains control and processes the featureManager
configuration to load the requested features into the server and start the required components. Finally, the applications are started. When the configuration is changed, the feature manager reevaluates the code that is required for the newly requested features by starting and stopping parts of the runtime as necessary without restarting the server. Changes to applications are processed in a similar way.
3.1. Using features
Features are specified in the system configuration files that are the server.xml
file and any other included files. The feature manager is configured by using the featureManager
element in the server.xml
file. Each feature that is required is configured by using the feature
element. The following example configures the servlet-4.0
and jdbc-4.3
features:
<server> <featureManager> <feature>servlet-4.0</feature> <feature>jdbc-4.3</feature> </featureManager> </server>
The runtime contains default configuration settings so that the configuration you need to specify is kept to a minimum. You specify the features that you need, along with any additions or overrides to the default settings, in the server.xml
file. For details about the server configuration, see the Server configuration overview.
3.2. Zero-migration
With the Open Liberty zero-migration architecture, you can move to the latest version of Open Liberty with minimal impact to your current applications and configurations. Zero-migration architecture means that you can use existing, unmodified configuration and application files with an updated version of the Open Liberty runtime environment without unwanted or unexpected change in behavior.
With the use of pluggable features in the Open Liberty runtime environment, your existing APIs and behaviors are supported in new product versions, and new APIs and behaviors are added in new features. For example, both the Servlet 3.1 and 4.0 specifications are supported. Changes in API behavior only happen in new feature versions, so you can choose the appropriate feature version for your application. These versioned features continue to be supported across Open Liberty updates.
If you continue to use the same feature version, you never need to migrate your application. For example, if your application uses Servlet 3.1, the Open Liberty server that runs the application must have the servlet-3.1
feature. You can update Open Liberty and continue to use the servlet-3.1
feature indefinitely, regardless of how many other Servlet specification levels are supported. You need to migrate your applications only if you choose to use the servlet-4.0
feature instead.
3.3. Combining features
If you try to configure a server to have different versions of a feature, an error is reported because Open Liberty doesn’t support combining different versions of the same feature. This means that most Open Liberty features are singleton features. A singleton feature is a feature for which you can configure only one version for use in a server.
If you have applications that need different versions of the singleton feature, you must deploy them in different servers. If your server configuration includes multiple versions of a singleton feature, either through direct configuration in the server.xml
file, or through feature dependencies, that configuration is in error and neither version of that feature is loaded. To resolve this problem, ensure that the configured features all specify, or tolerate, the same version of that singleton feature. If you have hard requirements on both feature versions, you must move some of your applications to a different server.
Liberty doesn’t support combining features from both Java EE 7 and Java EE 8, except when the Java EE 7 and Java EE 8 specifications share a component specification version. If you combine Java EE 7 and Java EE 8 features in a server configuration, the server reports errors at startup.
The following features are included in both Java EE 7 and Java EE 8:
For a complete list of features that support Java EE 7, see the javaee-7.0 feature. For a complete list of features that support Java EE 8, see the javaee-8.0 feature.
3.4. Superseded features
If a feature is superseded, a new feature or a combination of features might provide an advantage over the superseded feature. The new feature or features might not completely replace the function of the superseded feature, so you must consider your scenario before you decide whether to change your configuration. Superseded features remain supported and valid for use in your configuration, but you might be able to improve your configuration by using the newer features.
Occasionally, a feature that includes other features is superseded by a new version of the feature that does not include all those features. The features that are not included in the new version are considered to be separated. If your application depends on the functions of a separated feature, you must explicitly add the separated feature to your configuration.
The following table lists the Open Liberty features that are superseded:
Superseded feature | Superseding feature | Dependent feature removed |
---|---|---|
|
|
The ldapRegistry and the |
|
|
Together, the |
|
|
The |
Chapter 4. Server configuration overview
The Open Liberty server config is made up of one mandatory file, the server.xml
file, and a set of optional additional files. The server.xml
is the only mandatory config file. The only requirements for the server.xml
file are that it must be well formed XML and the root element is server
. When processing the server.xml
file, any elements or attributes that are not understood are simply ignored. The default server.xml
might look like the following example:
<server description="new server"> <featureManager> <feature>jsp-2.3</feature> </featureManager> <httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443" /> <applicationManager autoExpand="true"/> </server>
This example server.xml
configures the server to support Java Server Pages 2.3, to listen to incoming traffic to localhost on port 9080, and to automatically expand WAR files when they are deployed.
The server.xml
is described in more detail below. When discussing config for Open Liberty, the term "server config" can be used to refer to all of the files that make up the server config, or specifically to the config held in XML files; it is usually clear in context and, if not, the phrase "server XML config" might be used to clarify. The next few sections describe each of the config files in the order they are processed.
4.1. server.env
The server.env
files are optional but, when present, are read by the bin/server
script and specify environment variables primarily used to influence the behavior of the bin/server
script. server.env
files are read from the following locations in order:
-
${wlp.install.dir}/etc/
-
${wlp.user.dir}/shared/
-
${server.config.dir}/
If the same property is set in multiple locations the last value found is used.
The most common use of this file is to set the following settings:
-
JAVA_HOME
- indicates which JVM to use. If this is not set, the system default is used which often isn’t desired. -
WLP_USER_DIR
- indicates the location of theusr
directory which contains the server config. This can only be set in theetc/server.env
file because the other locations are relative to theusr
directory. -
WLP_OUTPUT_DIR
- indicates where the server should write files to. By default, the server writes to the directory structure that the config is read from. However, in some secure profiles the server config needs to be read-only and so the server must write files to another location.
The server.env
file format is in terms of KEY = value
and does not support variable substitution. For example:
JAVA_HOME=/opt/ibm/java WLP_USER_DIR=/opt/wlp-usr
Key values must not contain white space. The values are interpreted as literal so there is no need to escape spaces or other special characters.
4.2. jvm.options
The jvm.options
files are optional but, when present, are read by the bin/server
shell script to determine what options to use when launching the JVM for Open Liberty. The jvm.options
files are read from the following locations in order:
-
${wlp.user.dir}/shared/jvm.options
-
${server.config.dir}/configDropins/defaults/
-
${server.config.dir}/
-
${server.config.dir}/configDropins/overrides/
If none of these files exist, the server script looks for a file in ${wlp.install.dir}/etc
and uses that.
Common uses of jvm.options
files include:
- Setting JVM memory limits
- Enabling Java Agents provided by monitoring products
- Setting Java System Properties
The jvm.options
file format uses one line per JVM option and does not support variable substitution. For example:
-Xmx512m -Dmy.system.prop=This is the value.
There is no need to escape special characters, such as spaces.
The options are read and provided in order to the JVM. If you provide multiple options they are all seen by the JVM (most JVMs use the last option on the command line and ignore prior options). Certain options must not be put in the jvm.options
file such as -jar
.
4.3. bootstrap.properties
The bootstrap.properties
file is optional but, when present, it is read during Open Liberty bootstrap to provide config for the earliest stages of the server start-up. It is read by the server much earlier than server.xml
so it can affect the start-up and behavior of the Open Liberty kernel right from the start. The bootstrap.properties
file is a simple Java properties file and is located in ${server.config.dir}
. A common use of the bootstrap.properties
file is to configure logging because it can affect logging behavior before the server.xml
file is read.
The bootstrap.properties
file supports a special property, bootstrap.include
, which optionally specifies another properties file to also be read during the bootstrap stage. This include file could, for example, contain a common set of bootstrap properties to be used by multiple servers. Set the bootstrap.include
to an absolute or relative file path.
4.4. server.xml
The most important config file is the server.xml
file. It is a simple XML file format and the only requirement for the server to start is that the file is well-formed XML and has a root element called server
. The exact elements supported by a server depend on which features the server is configured so unknown config is simply ignored.
Open Liberty uses a principle of configuration by exception, allowing for very succinct config files. The runtime environment operates from a set of built-in config default settings. You only specify config that overrides those default settings.
Server config files are loaded in the following order:
-
${server.config.dir}/configDropins/defaults/
-
${server.config.dir}/server.xml
-
${server.config.dir}/configDropins/overrides/
The ${server.config.dir}/server.xml
file must be present but the other files are optional. This allows a very flexible way to compose config by simply dropping server-formatted XML files into directories. Within the two configDropins
directories the files are read in alphabetical order.
4.4.1. Variable substitution
You can parameterize server config using variables. When resolving variable names the following sources are consulted in increasing order of precedence:
-
server.xml
default variable values - environment variables
-
bootstrap.properties
- Java system properties
-
server.xml
config
Variables are referenced using ${variableName}
syntax. In server config, specify variables using the variable
element:
<variable name="variableName" value="some.value" />
Default values, specified in server config, are only used if no other value can be found. They are specified using the variable
element and the defaultValue
attribute:
<variable name="variableName" defaultValue="some.default.value"/>
Environment variables can be accessed as variables. From 19.0.0.3, they can be accessed directly by referencing the environment variable name. If the variable cannot be resolved the following transformations on the environment variable name is tried:
- Replace all non-alpha num characters with _
- Change all characters to upper case.
If you enter ${my.env.var}
in server.xml
it will look for environment variables with the following names:
- my.env.var
- my_env_var
- MY_ENV_VAR
When using a Liberty release older than 19.0.0.3, environment variables can be accessed by adding env.
to the start of the environment variable name:
<httpEndpoint id="defaultHttpEndpoint" host="${env.HOST}" httpPort="9080" />
Variable values are always interpreted as a String with simple type conversion. This can lead to situations where a list of ports (e.g. 80,443
) is interpreted as a single string rather than as two port numbers. In this case, the variable substitution can be forced to split on the ,
using a list
function. For example:
<mongo ports="${list(mongoPorts)}" hosts="${list(mongoHosts)}" />
Simple arithmetic is also supported for variables whose value is an integer. The left and right side of the operator can be a variable or a number; the operator can be one of +
, -
, *
, /
for example:
<variable name="one" value="1" /> <variable name="two" value="${one+1}" /> <variable name="three" value="${one+two}" /> <variable name="six" value="${two*three}" /> <variable name="five" value="${six-one}" /> <variable name="threeagain" value="${six/two}" />
There are a number of predefined variables:
-
wlp.install.dir
- the location where the Liberty runtime is installed. -
wlp.server.name
- the name of the server. -
wlp.user.dir
- the location of theusr
folder. Defaults to${wlp.install.dir}/usr
. -
shared.app.dir
- the location of shared applications. Defaults to${wlp.user.dir}/shared/apps
. -
shared.config.dir
- the directory that contains the server config. Defaults to${wlp.user.dir}/shared/config
. -
shared.resource.dir
- the location of shared resource files. Defaults to${wlp.user.dir}/shared/resources
. -
server.config.dir
- the directory that server config is stored in. Defaults to${wlp.user.dir}/servers/${wlp.server.name}
. -
server.output.dir
- the directory that the server writes the workarea, logs and other runtime generated files to. Defaults to${server.config.dir}
.
4.4.2. Config merging
The config can be made up of multiple files so it is possible, perhaps even likely, that two files provide the same config. In these situations the server config is merged using a set of simple rules. In Open Liberty, config is separated into singleton and factory config. Merging works differently for the two. Singleton config is used when configuring a single thing (e.g. logging); factory config is used when it is valid to configure multiple things, (e.g. an application or a data source).
4.4.2.1. Merging singleton config
For singleton config elements the config is merged. If two elements exist with different attributes both attributes are used. For example:
<server> <logging a="true" /> <logging b="false" /> </server>
is treated as:
<server> <logging a="true" b="false" /> </server>
If the same attribute is specified twice then it is treated as a last instance wins. For example:
<server> <logging a="true" b="true"/> <logging b="false" /> </server>
is treated as:
<server> <logging a="true" b="false" /> </server>
In some cases, config is provided using child elements that take text. In these cases the config is merged by using all of the values specified. The most common scenario is configuring features. For example:
<server> <featureManager> <feature>servlet-4.0</feature> </featureManager> <featureManager> <feature>restConnector-2.0</feature> </featureManager> </server>
is treated as:
<server> <featureManager> <feature>servlet-4.0</feature> <feature>restConnector-2.0</feature> </featureManager> </server>
4.4.2.2. Merging factory config
Factory config merges use the same rules as singleton config but, because it is valid to configure the same element and mean two different logical objects, merging doesn’t happen just because the element names match. Instead each element is assumed to be configuring a distinct object. If the logical object is configured by two instances, the id
attribute must be set on each of them to indicate they are the same thing. Variable substitution on an id
is not supported.
The following example configures two applications. One is myapp.war
and has a context root of myawesomeapp
and the other is myapp2.war
which has myapp2
as the context root:
<server> <webApplication id="app1" location="myapp.war" /> <webApplication location="myapp2.war" /> <webApplication id="app1" contextRoot="/myawesomeapp" /> </server>
4.4.3. Include processing
In addition to the default locations, additional config files can be brought in using the include
element. When a server config file contains an include
reference to another file, the server processes the contents of the referenced file as if they were included inline in place of the include
element. In the following example, the server processes the contents of the other.xml
file before processing the contents of the other2.xml
file:
<server> <include location="other.xml" /> <include location="other2.xml" /> </server>
By default, an include file must exist but, if the include file might not be present, the optional
attribute can be set to true
. For example:
<server> <include location="other.xml" optional="true" /> </server>
When including a file, you can specify the onConflict
attribute to change the normal merge rules. The normal merge rules can be replaced to ignore (IGNORE
) any conflicting config or to replace it (REPLACE
).
<server> <include location="other.xml" onConflict="IGNORE" /> <include location="other2.xml" onConflict="REPLACE" /> </server>
You can set the location
attribute to a relative or absolute file path or to an HTTP URL.
4.4.4. Config references
Most configuration in Open Liberty is self-contained but it is often useful to be able to share config. A common example of this would be the JDBC driver config being shared by multiple data sources, or sharing the classloader for JDBC driver classes so the classes are visible both to the DataSource and to an application. Any factory config element defined as a direct child of the server
element can be referred to.
A reference to config always uses the id
attribute of the element being referred to. The config element making the reference uses an attribute that always ends with Ref
. For example:
<server> <dataSource jndiName="jdbc/fred" jdbcDriverRef="myDriver" /> <jdbcDriver id="myDriver" /> </server>
4.5. Dynamic updates
The server monitors the server XML config for updates and dynamically reloads when changes are detected. Changes to non-XML files (server.env
, bootstrap.properties
, and jvm.options
) are not dynamic because they are only read at start-up. Any server XML config file on the local disk is monitored for updates every 500ms. Whether to check, and how often, can be configured. To configure the server to only check every ten minutes specify:
<config monitorInterval="10m" />
To disable file system polling and only reload when an MBean is notified specify:
<config updateTrigger="mbean" />
4.6. Log Messages
While the server is running it might output log messages that reference some config. When this happens an XPath-like structure is used. The element name is given with the value of the id
attribute inside square brackets. If no id
is specified in server config, an id
is automatically generated. From the server XML config in the following example, the logs reference the dataStore
element as dataStore[myDS]
and the child dataSource would be identfied as dataStore[myDS]/dataSource[default-0]
in logs.
<server> <dataStore id="myDS"> <dataSource /> </dataStore> </server>
Chapter 5. Logging and tracing
Open Liberty has a unified logging component that handles messages that are written by applications and the runtime, and provides First Failure Data Capture (FFDC) capability. Logging data written by applications using System.out
, System.err
, or java.util.logging.Logger
are combined into the server logs.
There are three primary log files for a server:
-
console.log
- This file is created by theserver start
command. It contains the redirected standard output and standard error streams from the JVM process. This console output is intended for direct human consumption so lacks some information useful for automated log analysis. -
messages.log
- This file contains all messages that are written or captured by the logging component. All messages that are written to this file contain additional information such as the message time stamp and the ID of the thread that wrote the message. This file is suitable for automated log analysis. This file does not contain messages that are written directly by the JVM process. -
trace.log
- This file contains all messages that are written or captured by the logging component and any additional trace. This file is created only if you enable additional trace. This file does not contain messages that are written directly by the JVM process.
5.1. Logging configuration
The logging component can be controlled through the server configuration. The logging component can be fully configured in server.xml
using the logging
element. However, logging is initialized before server.xml
has been processed so configuring logging through server.xml
can result in early log entries using a different log configuration from later ones. For this reason it is also possible to provide much of the logging configuration using boostrap.properties
and in some cases using environment variables.
5.2. Example logging configuration
Some common logging configuration examples are given in the following sections.
5.2.1. Managing log file storage
The console.log
file is created by redirecting the process stdout
and stderr
to a file. As a result, Liberty is unable to offer the same level of management, like log rollover, as it offers for messages.log
. If you are concerned about the increasing size of the console.log
file, you can disable the console.log
file and use the messages.log
file instead. All the log messages sent to console.log
are written to the messages.log
file, and you can configure file rollover.
To disable the console log, and configure messages.log
to roll over three times at 100Mb, use the following configuration:
com.ibm.ws.logging.max.file.size=100 com.ibm.ws.logging.max.files=3 com.ibm.ws.logging.console.log.level=OFF com.ibm.ws.logging.copy.system.streams=false
5.2.2. JSON logging
When feeding log files into modern log aggregation and management tools it can be advantageous to have the log files stored using JSON format. This can be done in one of three ways:
Using the
bootstrap.properties
file:com.ibm.ws.logging.message.format=json com.ibm.ws.logging.message.source=message,trace,accessLog,ffdc,audit
Using environment variables:
WLP_LOGGING_MESSAGE_FORMAT=json WLP_LOGGING_MESSAGE_SOURCE=message,trace,accessLog,ffdc,audit
Using the
server.xml
file:<logging messageFormat="json" messageSource="message,trace,accessLog,ffdc,audit" />
When using
server.xml
to configure json format some log lines are written in the default non-JSON format prior toserver.xml
startup which can cause issues with some tools. For example,jq
would have trouble understanding the log files.
5.2.3. Configuring logging for a Docker image
It is common in Docker environments to disable messages.log
and instead format the console output as JSON. This can be done using environment variables:
WLP_LOGGING_MESSAGE_FORMAT=json WLP_LOGGING_MESSAGE_SOURCE= WLP_LOGGING_CONSOLE_FORMAT=json WLP_LOGGING_CONSOLE_LOGLEVEL=info WLP_LOGGING_CONSOLE_SOURCE=message,trace,accessLog,ffdc,audit
This can be simply set when running the docker run
command by using -e
to set the envrionment variables:
docker run -e "WLP_LOGGING_CONSOLE_SOURCE=message,trace,accessLog,ffdc" -e "WLP_LOGGING_CONSOLE_FORMAT=json" -e "WLP_LOGGING_CONSOLE_LOGLEVEL=info" -e "WLP_LOGGING_MESSAGE_FORMAT=json" -e "WLP_LOGGING_MESSAGE_SOURCE=" open-liberty
5.2.4. Binary logging
Liberty has a high performance binary log format option that significantly reduces the overhead of writing trace files. Generally, when configuring binary logging, the console.log
is disabled for best performance. This must be enabled using bootstrap.properties
:
websphere.log.provider=binaryLogging-1.0 com.ibm.ws.logging.console.log.level=OFF com.ibm.ws.logging.copy.system.streams=false
The binaryLog
command line tool can be used to convert the binary log to a text file:
binaryLog view defaultServer
5.3. Configuration settings by source
The table below shows the equivalent server.xml
, bootstrap.properties
, and environment variable configurations along with brief descriptions. Full configuration documentation is available in the config reference for the logging element.
Server XML Attribute | bootstrap property | Env var | Description |
---|---|---|---|
hideMessage | com.ibm.ws.logging.hideMessage |
You can use this attribute to configure the messages keys that you want to hide from the | |
logDirectory | com.ibm.ws.logging.log.directory | LOG_DIR |
You can use this attribute to set a directory for all log files, excluding the |
Console Log Config | |||
consoleFormat | com.ibm.ws.logging.console.format | WLP_LOGGING_CONSOLE_FORMAT |
The required format for the console. Valid values are |
consoleLogLevel | com.ibm.ws.logging.console.log.level | WLP_LOGGING_CONSOLE_LOGLEVEL | This filter controls the granularity of messages that go to the console. The valid values are INFO, AUDIT, WARNING, ERROR, and OFF. The default is AUDIT. If using with the Eclipse developer tools this must be set to the default. |
consoleSource | com.ibm.ws.logging.console.source | WLP_LOGGING_CONSOLE_SOURCE |
The list of comma-separated sources that route to the console. This property applies only when |
copySystemStreams | com.ibm.ws.logging.copy.system.streams |
If true, messages that are written to the System.out and System.err streams are copied to process | |
Message Log Config | |||
com.ibm.ws.logging.newLogsOnStart |
If set to true when Liberty starts, any existing | ||
isoDateFormat | com.ibm.ws.logging.isoDateFormat | Specifies whether to use ISO-8601 formatted dates in log files. The default value is false.
If set to true, the ISO-8601 format is used in the
If you specify a value of | |
maxFiles | com.ibm.ws.logging.max.files |
How many of each of the logs files are kept. This setting also applies to the number of exception summary logs for FFDC. So if this number is | |
maxFileSize | com.ibm.ws.logging.max.file.size |
The maximum size (in MB) that a log file can reach before it is rolled. Setting the value to | |
messageFileName | com.ibm.ws.logging.message.file.name |
The message log has a default name of | |
messageFormat | com.ibm.ws.logging.message.format | WLP_LOGGING_MESSAGE_FORMAT |
The required format for the |
messageSource | com.ibm.ws.logging.message.source | WLP_LOGGING_MESSAGE_SOURCE |
The list of comma-separated sources that route to the |
Trace Config | |||
suppressSensitiveTrace |
The server trace can expose sensitive data when it traces untyped data, such as bytes received over a network connection. This attribute, when set to | ||
traceFileName | com.ibm.ws.logging.trace.file.name |
The | |
traceFormat | com.ibm.ws.logging.trace.format |
This attribute controls the format of the trace log. The default format for Liberty is | |
traceSpecification | com.ibm.ws.logging.trace.specification | The trace string is used to selectively enable trace. The format of the log detail level specification: component = level
where A component can be a logger name, trace group or class name. An asterisk * acts as a wildcard to match multiple components based on a prefix. For example:
|
Chapter 6. Testing with a container
You can use MicroShed Testing to develop integration tests for your Open Liberty application. You test your application from outside its container so that the tests run against the same image that you use in production.
To write a test with MircoShed testing, first add microshed-testing-testcontainers
and junit-jupiter
artifact IDs as test-scoped dependencies, as shown in the following example:
<dependency> <groupId>org.microshed</groupId> <artifactId>microshed-testing-testcontainers</artifactId> <version>0.4.1</version> <scope>test</scope> </dependency> <!-- Any compatible version of JUnit Jupiter 5.X will work --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.4.2</version> <scope>test</scope> </dependency>
Next, create a test class with the MicroShedTest
annotation. Then, create a public static MicroProfileApplication
method and inject one or more public static JAX-RS
resources, as shown in the following example:
@MicroShedTest public class MyTest { @Container public static MicroProfileApplication app = new MicroProfileApplication() .withAppContextRoot("/myservice"); @Inject public static MyService mySvc; // write @Test methods as normal
In cases where a Dockerfile or container image is not available, use the microshed-testing-liberty
adapter. This adapter produces a container image that is similar to the following Dockerfile:
FROM open-liberty:microProfile3 ADD build/libs/$APP_FILE /config/dropins COPY src/main/liberty/config /config
For more information, see MicroShed Testing.
Additional resources
Chapter 7. Debugging
7.1. Dev Mode
With Liberty dev mode, you can rapidly code, deploy, and debug applications with Liberty. You enable dev mode through the Liberty Maven-plugin.
To use dev mode, add the following code to your Maven pom.xml file and run the mvn liberty:dev
command.
<plugin> <groupId>io.openliberty.tools</groupId> <artifactId>liberty-maven-plugin</artifactId> <version>3.1.0</version> </plugin>
Dev mode provides three key features:
- Your running server can detect, recompile, and pick up code changes.
-
You can run unit and integration tests on demand, by pressing
Enter
in the command window where dev mode is running. - You can attach a debugger to the running server to step through your code at any time.
When you use dev mode, Liberty automatically detects the following changes to your application source:
- Java source file changes and Java test file changes.
- Dependencies that are added to your pom.xml file. Liberty detects the dependencies and adds them to your class path.
- Resource file changes. Liberty detects them and copies them into your target directory.
- Configuration directory and configuration file changes. Liberty detects them and copies them into your target directory.
- Addition of new features in the Liberty server configuration. Liberty detects the new features, installs them, and starts them.
Dev Mode does not detect some changes. These changes include the following ones:
- The addition of a configuration directory or file.
- Changes to the host and port for Liberty.
If either of these changes are made, Liberty can detect them after you restart dev mode. To restart, first exit dev mode by typing Control-C
, or by typing q
and pressing Enter
. Then, run the mvn liberty:dev
command to restart.
For more information, see Liberty Dev mode.
7.2. Managing build processes with the Open Liberty Maven plug-in
You can build and test your applications, whether they are simple applications with a single module or more complex applications that consist of multiple modules.
After you define the details and dependencies of a project, Maven automatically downloads and installs all of the dependencies. It also runs automated tests on an application after it is built. If the tests don’t pass after you update an application, the build fails. You must fix your code.
The following coordinates for the Maven plug-in are required:
<groupId>io.openliberty.tools</groupId> <artifactId>liberty-maven-plugin</artifactId> <version>3.1.0</version>
To learn how to configure a simple web servlet application by using Maven and the Liberty Maven plug-in, see Building a web application with Maven.
Jakarta EE applications consist of multiple modules that work together as one entity. To learn how to build an application with multiple modules by using Maven and Open Liberty, see Creating a multi-module application.
7.3. Tracing Requests
Distributed tracing helps you troubleshoot microservices by examining and logging requests as they propagate through a distributed system, allowing developers to tackle the otherwise difficult task of debugging these requests. Without a distributed tracing system in place, it’s difficult to analyze workflows and pinpoint when and by whom a request is received or when a response is returned.
To learn how to monitor and trace logging requests across microservices in an application, see Enabling distributed tracing in microservices.
Chapter 8. Monitoring Open Liberty
You can use MicroProfile Metrics and MicroProfile Health to monitor microservices and applications that run on Open Liberty. Enabling and reporting metric and health check data for your microservices helps you pinpoint issues, collect data for capacity planning, and decide when to scale a service up or down.
8.1. Enabling monitoring in microservices
Building observability into microservices externalizes the internal status of a system to enable operations teams to monitor microservice systems more effectively. It’s important that microservices are written to produce metrics that can be used by operations teams when the microservices are running in production.
Metrics are emitted from a number of different places. You can obtain them from applications, the Open Liberty runtime, and the Java virtual machine (JVM). MicroProfile Metrics provides a /metrics
endpoint from which you can access all metrics that are emitted by the Open Liberty server and deployed applications. They can be gathered and stored in database tools, such as Prometheus, and displayed on dashboards, such as Grafana.
Metrics come in various forms, including counters, gauges, timers, histograms, and meters. You can enable metrics in your Open Liberty application with the MicroProfile Metrics feature, which defines annotations that help you quickly build metrics into your code.
For a list of all available Open Liberty metrics, see the metrics reference list.
To learn how to use MicroProfile Metrics to enable and provide metrics from a microservice, see Providing metrics from a microservice.
Additional Resources
8.2. Enabling health checks in microservices
A health check is a special REST API that you can use to validate the status of a microservice and its dependencies. MicroProfile Health enables services in an application to self-check their health and then publishes the overall health status to a defined endpoint.
A self-check can be used to assess anything that the service needs, such as:
- Dependencies
- System properties
- Database connections
- Endpoint connections
- Resource availability
With MicroProfile Health, you can enable the services in your liberty application to self-check for liveness and readiness. A liveness check determines whether a service encountered a bug or deadlock. If this check fails, the service is not running and can be terminated. This check corresponds to the Kubernetes liveness probe, which automatically restarts the pod if the check fails. A readiness check determines whether a service is ready to process requests. This check corresponds to the readiness probe in Kubernetes.
To learn how to use MicroProfile Health to enable and report microservice health checks, see Adding health reports to microservices.
Additional resources
Appendix A. Additional Open Liberty resources
You can learn more about Open Liberty and the APIs it supports by viewing resources on the Open Liberty website.