I am using Spring AOP with #AspectJ syntax in my project. May I know how to get the output in a file? Does any way to do that already exist?
Since your question is very vague, it is hard to give you an exact answer.
But the intuitive way would be to add a logger from a logging framework like Log4J or LogBack (preferable accessed through SLF4J) in your aspect class and configure the appender to write to a separate file.
Or to separate things more cleanly, you may write a separate aspect that wraps the other aspect and does logging. But pay attention to Advice Ordering if you do it that way.
Related
New to Spring Boot here, long-time Spring Framework user though.
I'm looking for a way to split my externalised configuration into multiple .properties files, for better readability and manageability.
I already saw this SO answer: having the ability to specify a list of configuration file names in spring.config.name (which, by the way, doesn't seem to be mentioned in Boot reference documentation, correct me if I'm wrong) would solve my problem perfectly, however that configuration property can be specified only via system properties or environment variables. If I try to specify it inside my application.properties file, it gets ignored. The same happens for spring.config.additional-location. I understand this happens because, when application.properties is read, it's too late to tell Spring Boot to search for different externalised configuration file names. However this is not a proper solution, because the way I split my configuration should be an "implementation detail" that the consumer of my application shouldn't be aware of, so I don't expect the consumer to specify an external parameter otherwise my application breaks out-of-the-box.
I think that a way to do this should be provided. Perhaps some import mechanism for .properties files or the ability to specify spring.config.name even in application.properties (some known and reasonable limitations would be acceptable).
The best I could find out is to use #PropertySource, but this is not profile aware: unless you use some ugly nested class hack, or you put spring.profiles.active variable in the resource name (which will break if multiple profiles have been activated), you won't get the benefit you have for application.properties profile-specific files.
I was not able to find an "official way" to do this, apart from some statements from Spring Boot devs that say that they're rather promoting the use of a single (possibly giant...) externalised configuration file. It seems like this position is not so popular, judging from the post reactions on GitHub, and IMHO it really seems to be a basic feature missing. I have been working with multiple properties files in Spring Framework (using XML configuration) for years and I never felt that having an only huge file would have been better.
If I understand it right, in Boot 1.x this was in some way possible using the location attribute of #ConfigurationProperties, which is however missing in Boot 2.x.
Any suggestion?
Have you tried with Spring Profile?
What you can do is create application-file1.properties/yml, application-file2.properties/yml and put it in config location and then add spring.profile.active=<your env profiles>,file1,file2.
It will load the files.
This profile entry can be in bootstrap.yml, or JVM args to application, in Manifest-<env>.yml in case of Pivotal Cloud Foundry. Not sure on AWS and other cloud provider.
Hope this will help.
Over the course of writing Spring Boot apps, our team adds in a lot of #Value annotations to help make things configurable. At some point we start to lose track of exactly what we added and what can be configured. We get a lot of questions from the QA and DevOps teams about what exactly can be configured and what can't.
Currently we just do a grep through the code base and apply some crude regular expressions to try and parse out the meaningful pieces. But this doesn't catch 100% of cases and inevitably we end up digging through the code to find out what fields can be configured.
I know we could use JavaDoc to somewhat achieve our goal, but the documentation would be buried with other JavaDoc (methods, fields, classes, etc) and it's still reliant on developers to remember to add the JavaDoc to each field.
Has anyone found a more automated way to document their #Value fields? I'm thinking something like Swagger, but specifically for Spring and the various ways it can externalize configuration.
Javadoc is indeed a way to document for developers, not the QA or the operators.
Your question is really interesting but answering to that canonically is hard because #Value are implementation details of components. Swagger that you quote documents REST contracts, that is an important difference.
Here some ideas :
Writing a BDD test for them that could be used too as documentation makes really no sense functionally but technically it makes.
Indeed, you could write a BDD integration test (with Cucumber or any other library) where you document and test the presence of each expected property.
Not a perfect solution, but you could at least retrieve exposed properties and a little more with these Spring Boot actuators :
configprops : Displays a collated list of all #ConfigurationProperties.
env : Exposes properties from Spring’s ConfigurableEnvironment.
Whenever you can, favor #ConfigurationProperties injection to group properties that work together rather than #Value. Isolating them in #ConfigurationProperties classes and adding javadoc for them is not bad at all to document their presence and usage.
as suggested by caco3 you can also generate your own metadata by using the Annotation Processor :
You can easily generate your own configuration metadata file from
items annotated with #ConfigurationProperties...
The processor picks up both classes and methods that are annotated
with #ConfigurationProperties. The Javadoc for field values within
configuration classes is used to populate the description attribute.
It joins with the previous point : favoring #ConfigurationProperties whenever it is possible.
Reading the Spring AOP documentation (link), I'm having a hard time (maybe also because english is not my native language) understanding these paragraphs.
First, I read
Further, in certain environments, this support enables load-time
weaving without making any modifications to the application server’s
launch script that is needed to add
-javaagent:path/to/aspectjweaver.jar or (as we describe later in
this section)
-javaagent:path/to/org.springframework.instrument-{version}.jar
(previously named spring-agent.jar).
And
Developers modify one or more files that form the application context
to enable load-time weaving
Which files? #Aspect classes and aop.xml files?
Then, when describing an example in the same sub-chapter, they say
We have one last thing to do. The introduction to this section did say
that one could switch on LTW selectively on a per-ClassLoader basis
with Spring, and this is true. However, for this example, we use a
Java agent (supplied with Spring) to switch on the LTW. We use the
following command to run the Main class shown earlier:
And they apply a Java Agent to the JVM.
-javaagent:C:/projects/foo/lib/global/spring-instrument.jar
Now I have a couple of doubts.
If I #EnableLoadTimeWeaving, do I need the spring-instrument Jar file as Java Agent?
I suppose the answer is yes, because we need to add bytecode to the class file before loading it. But a confirmation would be much appreciated.
The Jar naming is a little ambiguos, first they mention spring-agent.jar, then they use org.springframework.instrument-{version}.jar, and then spring-instrument.jar.
Are we always talking about the same Jar file?
I see from another question you asked that you are using Spring Boot and running a fat jar. In this case you don't need #EnableLoadTimeWeaving or spring-instrument (formerly known as spring-agent). Just ignore them if you are not running in an appserver for which you don't control the agent path.
I opened an issue for you about the confusion in the docs: https://github.com/spring-projects/spring-framework/issues/22429.
I am having problems integrating perf4j in an existing maven application.
I tried several approaches, but none of them seemed to work, so I was wondering if anyone has some insight into how this is done.
What I want to do is use the AOP part of perf4j on some methods and log them into a different file than the one used for app logging. Thanks
You might be suffering from the same declaration order issue as mentioned in another perf4j/logback related question. In short, it is always a good idea to enable printing of logback's internal status messages by setting the debug attribute to true within the configuration element. Also do not forget that any referenced appender must be declared beforehand.
I am using Spring framework in my application and it is deployed on MULE server.
Based on debug or info level, the amount of logging and the percentage of logging will vary.
Till date, I write the log statements explicitly in all my business logic.
Is there any way to do this through configuration, say configure at some point -
CLASS NAME - METHOD NAME - LOG AT ENTRY POINT WITH INPUT PARAMETERS - LOG AT EXIT POINT WITH RETURN
This way my code will not look very clutter.
I am not sure exactly what you are asking, but it sounds like you would like to automatically log entry and exit from methods along with parameters. If that is the case, you might consider some form of Aspect Oriented Programing (AOP). Here and here and here are some links to pages with good examples of implementing exactly this kind of logging with PostSharp. Since you are using Spring (.NET or just Spring?), you might know that Spring.NET has an AOP solution (or here for Spring). Here is a project from CodeProject that provides a log4net logging aspect already written for PostSharp (not sure if this is currently up to date or not). There are other AOP solutions out there, PostSharp is one of the more popular.
I answered with a .NET slant because that is what I am more familiar with and you didn't indicate a language preference (via the tags) in your question.
As wageoghe mentioned, using Spring AOP is an option.
Another one, since you're running in Mule, is to use component interceptors around your Spring beans.