Catalyst Log4perl: configure config file location from app config - perl

In a Catalyst app, I need to specify the Log4perl's config file location. All the examples I could find suggest that I should do that from code. However, I would like to be able to specify it in the app config file. This would allow me to use different log configs for different environments and manage all that from a single file. I would also like to be able to set log levels from app config file.
However, there seems to be no documented way of configuring the logger from the app config file. I tried multiple variations of syntax, but none was picked up by Catalyst. It is also impossible to set the correct config file name from MyApp.pm (main app module), as configuration is not yet available when module code is run.
Debugging the logger initialization code also didn't help. The only real way I am considering now is to require a config file from MyApp.pm, which would include the necessary configuration.
The questions thus are:
Is there a way to specify the Log4perl config file location from Catalyst config file?
Is there a way to specify log levels from a config file?

I thought I'd googled enough, but apparently I hadn't.
__PACKAGE__->setup();
__PACKAGE__->log(Log::Log4perl::Catalyst->new(__PACKAGE__->path_to(__PACKAGE__->config->{Log}->{config_file})->stringify));
(ref http://www.gossamer-threads.com/lists/catalyst/users/31271).
And as for log levels: they are defined in the actual Log4perl config file.

Related

How do I run a project in eclipse with different jboss-ejb-client.properties

I have EJBs deployed on several different servers, for different environments. I have many projects that use these EJBs. I usually just run my projects against the DEV server EJBs, but sometimes I need to run against the TEST or PROD environment EJBs. This necessitates having to comment out all of the DEV nodes in my jboss-client-ejb.properties file and uncomment all of the TEST nodes. But then if I forget to change them back, I may mess up some data if I run it later. What I would like to do is create a different runtime configuration for each environment, and have each runtime config use a different version of the jboss-client-ejb.properties. Is there a way to do this? If so how? I have looked at all of properties of a run configuration, and don't see anything helpful.
In eclipse preferences search for string variable substitution. Here create variables that point to multiple config files for each of your environments. Then create multiple run configurations and for each one (like dev or prod) add a program argument that points to your string variable defined in your preferences like this -DmyconfigFile={$MyDevPropertiesFilePath}, or you could hard code the config path and have multiple runtime configurations that use different config files. Key point here is create multiple runtime launch configurations for each environment and add the properties for each environment that point to the config file respective to each environment. This way you can easily select the launch menu and decide to run "dev" "prod" or whatever you name your multiple configurations. Trying to do this with one runtime configuration will cause pain as you say, because it is easy to forget to revert or change the config file you want to to use. Hope that helps. Also if you create a new workspace you can export your runtime configurations using the export wizard which is also helpful for passing on to other developers or putting in source control.
P.S Looking more at your question you wan to pass in the config file path as a program argument, you are correct there are no specific options for setting this file path. Using program arguments with multiple launch configurations.

Superseding scala conf file as JVM argument?

I have an application.conf file that is read by my program (via com.typesafe.config) at each run. I would now like to keep only standard settings in that file, and be able to specify a superseding conf file thisrun.conf for each run (i.e. the app should use configs from thisrun.conf and fall back on application.conf for any missing configs).
Can this be done by simply passing the thisrun.conf file as a parameter to the JVM, or do I have to pass it as an argument to my app? A previous question shows how to pass a config file using -Dconfig.file, but this seems to bypass application.conf, rather than supersede it.
I found one way of superseding application.conf with thisrun.conf using the -Dconfig.file argument. Simply put as the first line in thisrun.conf:
include "application.conf"
This way the behavior will be exactly as asked in the question.
I would still be interested if there are other ways of doing the same, that do not require an explicit include of application.conf.

environmental variable substitution when including another configuration file in Play 2.2

Is it possible to use environmental variable substitution when including another configuration file?
I would like to have something like that:
include "${HOME}/.foo/credentials.conf"
Configuration documentation mentions locating resources and include substitution but not together.
This works:
include "/home/me/.foo/credentials.conf"
and my HOME is correctly set.
But all attempts to make include "${HOME}/.foo/credentials.conf" so far failed
Background:
I deliberately want to keep credentials and other sensitive data out of our code base but have them available for local dev environments for testing. I am aware of more sophisticated solutions using external storage like hinted here Playframework 2 - Storing your credentials and we use something similar for live and preview environments but these are not suitable for local dev setup.
An alternative is to include credentials file to code base after all but use git ignore to prevent pushing it, but it is fragile solution and risk is someone will eventually push it and compromise credentials.
TBH I'm not even able to include file with absolute path /home/me... anyway approach which will work for you is just using alternative conf file as described in the same doc:
In file /home/me/.foo/credentials.conf you need to include application.conf - Play will fallback it to the file in classpath (this which is under VCS):
include "application.conf"
myCredentials.user="Espinosa"
myCredentials.password="fooBar123"
then run/start your app with this config file locally:
play -Dconfig.file=${HOME}/.foo/credentials.conf ~run
and that's it.
Note: of course it's easier to setup this addition in your IDE (i.e. IntelliJ: Run > Edit configurations) or write a shell script containing this command

Play Framework - How to maintain configuration files for different environments?

For my Play 2.2/Scala application (built with SBT), I would like to deploy different configuration files depending on the environment I'm deploying to (e.g. to couple a deployment with a particular database server). How does one create different variants of the application's configuration file (conf/application.conf) for different deployment targets? Hopefully variants can be generated from a base version?
What I'm used to from .NET is to have a base configuration file (Web.config), which undergoes a certain transformation depending on the profile one is deploying (e.g. Production). Does one use a similar technique in the Play/Scala world?
Alternative configuration files are covered in Play's documentation quite well in section Specifying alternative configuration file.
In short - in application.conf you place default configuration of your app, and additionally you need to create additional files for you environment(s) ie. life.conf, dev.conf etc. In these files you first need to include application.conf (which will read whole default configuration) and next just overwrite only parts which have to be changed - ie. DB credentials, it could be dev.conf:
include "application.conf"
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:alternative-database-for-dev-testing"
db.default.user=developer
db.default.password="developerpass"
So finally you start your application (after dist) as
./start -Dconfig.resource=dev.conf
or with the Play console
play -Dconfig.resource=dev.conf run
Several tips:
It's good idea to do not place your 'life' DB credentials in default application.conf file, if some dev will forget to include his dev.conf he won't damage the production DB, instead you should put it in prod.conf.
Also these additional configs shouldn't be placed in any VCS (ie. git) repository - creating them directly on target machine (and ignoring in repository) give you sure, that people who shouldn't know the life database credentials won't see it.
It's also possible to use remote alternative config file, which can be useful ie. when you deploying several instances of the same app ie. on several hosts in the cloud.
Each dev can has own config file ie dev_aknuds1.conf, dev_biesior.conf etc, so you can ignore them with one pattern dev_*.conf in repo.
Finally you can just create a shell script (unix) or bat file (Windows) to start using choosen config file like start_dev.sh, run_dev.sh etc. so you won't need to write -Dconfig.resource=... each time

Configuration centralization for Play2 Scala; or how to stop hardcoding variables

At the moment, I'm hardcoding several variables like resource names and ports. I would like to move them out of my code.
What are recommended means of implementing a central configuration outside the actual code? Like a file maybe. So that, while the production and development are using same git repository, the configurations would be seperate. I am using Play 2 Framework on Scala.
I would suggest using the Typesafe Config library. It loads and parses files that can be a mix of .properties style, JSON, or extended JSON (called HOCON - "Human-Optimized Config Object Notation"), and is the configuration style used by Play 2 itself (and Akka, Spray, and a quickly growing list of other libraries).
In Play's standard application.conf file you can include files like so:
include "file:///..."
In this file you could override what properties you need to.
Additionally, (as documented in the excellent play docs), one can specify conf files during app startup like so:
Using -Dconfig.file
You can also specify another local configuration file not packaged into the application artifacts:
$ start -Dconfig.file=/opt/conf/prod.conf
Using -Dconfig.url
You can also specify a configuration file to be loaded from any URL:
$ start -Dconfig.url=http://conf.mycompany.com/conf/prod.conf
Note that you can always reference the original configuration file in a new prod.conf file using the include directive, such as:
include "application.conf"
key.to.override=blah
Configuration is likely a mean of taste, but Typesafe Config is one of the common libraries to use in scala/play ecosystem (e.g. it is used in akka).