I am reading log4j docs and logstash log4j config , i don't know ${sys:ls.logs} mean.
What mean ${sys:ls.logs}?
How can i change this valuable in runtime or in OS environment.
I use Ubuntu OS.
sys is System properties in Log4j 2. Log4j supports the syntax ${prefix:name} where the prefix identifies tells Log4j that variable name should be evaluated in a specific context. See Log4j 2 documents
sys : System properties. The formats are ${sys:some.property} and ${sys:some.property:-default_value}.
Property Support
You can reference properties in a configuration, Log4j will directly replace them, or Log4j will pass them to an underlying component that will dynamically resolve them. Properties come from values defined in the configuration file, system properties, environment variables, the ThreadContext Map, and data present in the event.
System properties are often defined outside the application and you can access them via a Lookup. You can further customize the property providers by adding their own Lookup Plugin. Default properties may also be specified in the Lookup by using the syntax ${lookupName:key:-defaultValue}.
<Appenders>
<File name="ApplicationLog" fileName="${sys:logPath:-/var/logs}/app.log"/>
</Appenders>
Furthermore, using a lookup for the system property named ls.logs, in Log4j 1.x, the syntax would be ${ls.logs}. In Log4j 2, the syntax would be ${sys:ls.logs}.
This property may be set in app source or as an argument when start the service. For example, in a DefaultDeprecationLoggerTest for logstash in logstash source it is set to build/logs as below:
#Before
public void setUp() throws IOException {
System.setProperty("log4j.configurationFile", CONFIG);
System.setProperty("ls.log.format", "plain");
System.setProperty("ls.logs", "build/logs");
LogTestUtils.deleteLogFile("logstash-deprecation.log");
}
Related
I need to add to my logging.properties the line:
sun.net.www.protocol.http.HttpURLConnection.level = ALL
But this file is generated using log4j.xml, which is in xml format. And I'm not finding how to correctly format this property to xml to generate this line.
using log4j-1.2.8, JRE and JDK 1.8_181, Wildfly 10.1.0.Final
At first glance, you will not be able to configure the logging level for sun.net.www.protocol.http.HttpURLConnection using Log4j, no matter if you use properties or xml configuration files.
As you can see in the source code of the HttpURLConnection class, its logging is based in PlatformLogger, which in turn uses java.util.logging.
The PlatformLogger javadoc describes how it should be configured:
Platform logger provides an API for the JRE components to log
messages. This enables the runtime components to eliminate the
static dependency of the logging facility and also defers the
java.util.logging initialization until it is enabled.
In addition, the PlatformLogger API can be used if the logging
module does not exist.
If the logging facility is not enabled, the platform loggers
will output log messages per the default logging configuration
(see below). In this implementation, it does not log the
the stack frame information issuing the log message.
When the logging facility is enabled (at startup or runtime),
the java.util.logging.Logger will be created for each platform
logger and all log messages will be forwarded to the Logger
to handle.
Logging facility is "enabled" when one of the following
conditions is met:
a system property "java.util.logging.config.class" or
"java.util.logging.config.file" is set
java.util.logging.LogManager or java.util.logging.Logger
is referenced that will trigger the logging initialization.
Default logging configuration:
global logging level = INFO
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
Basically, you need to configure the system property java.util.logging.config.file pointing to an appropriate properties file with the required properties:
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=INFO
sun.net.www.protocol.http.HttpURLConnection.level=ALL
Please, consider review this related SO question, it provides different examples and further information about how to do it.
As suggested in that question, you can use the system property javax.net.debug as well:
-Djavax.net.debug=all
If you want to integrate Log4j and java.util.logging, you can try using libraries like SLF4J and the corresponding bridges. This related SO question provides more information.
Remark: Since Log4j 1.2.8 is almost 20 years old, declared end-of-life 8 years ago and with several outstanding vulnerabilities, I don't believe you want to use it.
As you can see in jccampanero's answer, the HttpURLConnection class uses PlatformLogger for logging, which in Java 7 or 8 delegates all logging to java.util.logging.LogManager.
Several alternative implementations of java.util.logging.LogManager exist, but WildFly uses its own implementation called JBoss LogManager, which is the easiest to use. To modify your logging configuration, you just need to edit your server's configuration and add:
<subsystem xmlns="urn:jboss:domain:logging:3.0">
...
<logger category="sun.net.www.protocol.http.HttpURLConnection">
<level name="DEBUG"/>
</logger>
</subsystem>
(cf. documentation).
My question is another question about configuration in spring boot (v 2.2.x) but I have one significant difference in my config structure in comparison to configuration in existing posts on SO about configs (i.e. spring boot external config) I have following application configurations:
--src\
--main\
--resources\
-- application.yml
-- application-local.yml
-- application-dev.yml
-- application-prod.yml
My application-prod.yml looks like:
spring:
profiles:
active: prod
include:
customization
logging:
level:
root: INFO
org.springframework: INFO
org.hibernate.SQL: INFO
org.hibernate.type: INFO
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss} - %msg%n'
file: '%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n'
file: ./logs/goals-service.log
My prod config have to use (this is a business requirement) external configuration with setting of
db connection,
security settings
endpoints and credentials of other services.
I would like to use standard approach and ability of spring to automatically config beans, i do not want to manually load some property file and configure all beans manually. Therefore to solve this issue i created another config application-customization.yml and link it in prod config via include (see in example above). And here i faced a problem: i am unable to select path to application-customization.yml via command line argument (-Dspring.config.location or any it variations) , but i could load customization settings when i placed my external config in directory that is used to start app (this is a behaviour of spring to search configs), and app in this case works fine. I would like to pass path of where app should search my application-customization.yml, and one more thing i can'not use symlinks from to link from actual config location to ./application-customization.yml.
Remove that "include" from your application-dev, because I have no idea how it will interact with anything that I'm going to say. Then there are (at least) two simple ways to do what you want. (There are also some complicated ways -- overkill for your situation, and indeed most situations -- like overriding this or defining one of these.)
Way 1: pass -Dspring.config.location=X to the JVM, where X is a comma-separated list of locations containing files Spring should read. In your case, you probably want -Dspring.config.location=file:/some/folder/,classpath:/; the first location will ensure you fulfill your business requirement and the second will ensure the app also reads the application-dev.yml inside its own jar.
Way 2: put #PropertySource("file:/some/folder/application.properties") on a class annotated with #Configuration (note that #SpringBootApplication is meta-annotated with #Configuration). This has two issues: one, the file in the #PropertySource is read last and the properties therein do not override properties which were read earlier; two, there are some properties which you cannot set with an #PropertySource file (because the file is read too late in the startup process). I don't think either issue will bother you, but I wanted to note them for other readers.
Note on Tomcat (and presumably other containers): using way 1 there is a bit complicated, since spring.config.location is a system property; it might require faffing about with app-specific web.xml files. EDIT 2020-09-04: Or you could do this (specifically the third snippet in that code, which I repeat, modifying the property name and value, in case that answer ever vanishes:
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class).properties("spring.config.location: /my/config1/,/my/config2/");
}
}
)... which is better.
This answer has mostly been a regurgitation of the excellent official documentation on this and related questions.
I have a config.properties file which contains configurable properties e.g. database connection details in a webapp deployed on tomcat. e.g.
local.driver: com.mysql.jdbc.Driver
local.username:myuser
local.password:mypass
dev.driver: com.mysql.jdbc.Driver
dev.username:mydevuser
dev.password:mydevpass
I can retrieve the values from config.properties using spring Environment object or #Value.
My question is how do you make Spring's environment object pick local properties when running on local and dev properties when running on dev? Also it doesn't sound right to save sensitive data e.g. production database connection
details in properties file which will float around in code base. So how do you add production detail when in production environment? Ideally I would want to change them as and when I like and not have to redeploy the app. Am I going the right direction?
Note - All the answers I have seen on SO discuss changing these properties within java code. I don't want to do that I want to be able to configure these values independent of the application code.
Thanks
You can have a look at spring profiles to load a specific file for a specific environment.
Alternatively, you can also parameterize the file from where the properties are loaded in the application context using a JNDI property or an environment property set in the container.
Example:
<context:property-placeholder ignore-unresolvable="true" location="${env.config.file:classpath*:META-INF/spring/profiles/dev/dev.properties}" />
The env.config.file can be set at the container level (say Tomcat) using -Denv.config.file= when starting it. By doing this, Spring automagically finds the property in the system props and replaces it. If you don't set it explicitly (for example, in dev where you might use some other container, such as jetty), it would use the given default value (in this example, dev.properties).
By putting the properties files outside the war / ear, they can be changed at will, and only the context needs to be restarted. Alternatively, you could look into re-loadable property placeholders. This also helps if you don't want passwords stored in the war in clear.
For encrypting information in the property files, if you're using Spring 3, you can also check: http://www.jasypt.org/spring3.html.
for picking env specific values you have couple of options
If you can create multiple properties file based on env then you can use Spring profile feature (i.e spring.profiles.active), this will allow to control properties file to loaded via JVM parameter.
If you still want to keep all the stuff in single fle then you can override PropertyPlaceholderConfigurer to take env details from JVM parameter or default to some value
On security question , one the approach is to store encrypted password in prop file.
I have several Spring based apps - web, web services
For my web services project, in my ws-config.xml file, I specify the location of the wsdl. This has been set to localhost in the past, but I now need to have this as a configurable value in a properties file if I can.
<ws:dynamic-wsdl id="ServiceDefinition"
portTypeName="Test" locationUri="http://localhost/Test/webservice">
<ws:xsd location="/WEB-INF/schemas/my-test.xsd" />
</ws:dynamic-wsdl>
I need to be able to reference the locationUri as a property, but I dont know how to do it?
Can anyone help?
Check out the PropertyPlaceHolderConfigurer. You can use this to specify properties in your Spring configs, and specify which properties sources to populate this property from. You can specify a hierarchy of sources, such that (say) you have a file of default properties, and then some overridden values in a per-user config.
Here's a trivial example.
Our Java WebStart application does not include a log4j configuration file; it simply sets up some hardcoded loggers and appenders.
I would like individual clients to be able to drop a log4j.properties file in somewhere and set up their own custom logging in troubleshooting situations. I could bundle a log4j.properties file into one of the jars of our application somewhere and that would allow configuration, but then the configuration would be the same for each client instead of only affecting the client that I want to troubleshoot. Plus, I wouldn't be able to change settings on the fly.
Is there a way I can hijack the log4j initialization procedure to use a per-client configuration file?
The basic problem here, is that Java Web Start severely restricts the access to the machine.
You should be able to do this, if you are running a signed application AND the user allows you full access to the machine. If not, you cannot do this with log4j with the default mechanism.
You may want to write your own configurator which reads from the file system using the Java WebStart API an then feeds that to log4j, but it will require some elbow grease.
You could use the PersistenceService to store the log4j configuration on the local user's machine (works without signing), or at least store a flag on whether to load a special config or not at startup of your web start application.
There is also a FileOpenService with which the end-user could open a local log4j.xml file to re-configure the logging facility on the fly. That way, the user has the control over the configuration and he has the control when and where to apply it.
Your app code which uses the FileOpenService to get the stream to the log4j configuration file can then use the DOMConfigurator.configure(InputStream) to reconfigure log4j.