Is there any way to set the raygun tags in config level
I have tried in code level for exception
new RaygunClient().SendInBackground(exception, new List<string> { "Error", "Mq-Translator" });
But I would need to set the tag in project level for the service
If you are using the RaygunAppender from log4net raygun on nuget, the tags are set from:
.SetTags(ExtractTags(loggingEvent.GetProperties()))
This will extract all the properties set in the logging context.
If you set the properties as explained on the set properties on context manual they will show up in the tags.
Related
I'm developing a jee application which has to look at two files in order to load configuration parameters. Both files are properties-like files.
The first one contains a default configuration properties and the other one overrides them. So the first one is read-only and the other one can be modified. I need to react and update changes made on second configuration file.
I've take a look on several resources:
Composite Configuration
Combined Configuration
Combining Configuration Sources
I've not been able to figure out what and how to make configuration strategy with commons-configuration2.
Up to now, I've been able to read from one configuration file:
FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
new FileBasedConfigurationBuilder<PropertiesConfiguration>(PropertiesConfiguration.class)
.configure(new Parameters().properties()
.setFileName(ConfigurationResources.PROPERTIES_FILEPATH)
.setThrowExceptionOnMissing(true)
.setListDelimiterHandler(new DefaultListDelimiterHandler(';'))
.setIncludesAllowed(false));
Any ideas?
You need CombinedConfiguration. Here is the sample code
Parameters params = new Parameters();
CombinedConfigurationBuilder builder = new CombinedConfigurationBuilder()
.configure(params.fileBased().setFile(new File("configuration.xml")));
CombinedConfiguration cc = builder.getConfiguration();
Here configuration.xml file would contain the list of property files
<configuration systemProperties="systemProperties.xml">
<!-- Load the system properties -->
<system/>
<!-- Now load the config file, using a system property as file name -->
<properties fileName="myprops1.properties"/>
<properties fileName="myprops2.propert"/>
</configuration>
This documentation on Combined Configuration will be really helpful
Parameters params = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> config1 = new FileBasedConfigurationBuilder<FileBasedConfiguration>(
PropertiesConfiguration.class)
.configure(params.properties().setFileNamesetFileName("file1.properties")));
FileBasedConfigurationBuilder<FileBasedConfiguration> config2 = new FileBasedConfigurationBuilder<FileBasedConfiguration>(
PropertiesConfiguration.class).configure(params.properties().setFileName("default_file2.properties"));
CombinedConfiguration config = new CombinedConfiguration(new OverrideCombiner());
config.addConfiguration(config1.getConfiguration());//this overrides config2
config.addConfiguration(config2.getConfiguration());
return config;
This is something I have used in my project to create a combined configuration. A combined configuration naturally creates a hierarchy of configurations taken from different or same source. For example you could also write something like : FileBasedConfigurationBuilder<FileBasedConfiguration> config2 = new FileBasedConfigurationBuilder<FileBasedConfiguration>( PropertiesConfiguration.class).configure(params.properties().setFileName(System.getProperty("default_file2.properties")));
The FileBasedConfigurationBuilder can be substituted with any kind of configuration you may like. Refer to the link https://commons.apache.org/proper/commons-configuration/apidocs/org/apache/commons/configuration2/builder/BasicConfigurationBuilder.html
I am trying to figure out how to use the ExtendedLog4NetLogger.cs
to change the log file path dynamically at runtime or using the LoggingFacility?
This should be something similar to using log4net directly like this:
log4net.GlobalContext.Properties["LogName"] = logName;
How would I access the ExtendedLogger if I register log4net integration like this:
container.AddFacility<LoggingFacility>(f => f.UseLog4Net());
Update: I use the following code to register the Extended Logger
container.AddFacility<LoggingFacility>(LoggerImplementation.ExtendedLog4net).WithConfig(configFile).ToLog(Logger));
I get no runtime exceptions and the logger is not a null instance but I don't see the log file created at all using the global properties, I also set the config value to this for the appender: <file type="log4net.Util.PatternString" value="%property{LogName}" />
If I just set the file property in the config file to full path it does work. I am wondering if it is not working because configuration is done before setting the global variable.
extendedlogger.GlobalProperties["logName"] = logName;
To enable extended logger you need to do:
container.AddFacility<LoggingFacility>(f => f.LogUsing(LoggerImplementation.ExtendedLog4net));
1. How would I access the ExtendedLogger if I register log4net integration like this:
Using the dependency injection you can expect IExtendedLogger object in the place where you need it.
2. I am wondering if it is not working because configuration is done before setting the global variable.
That's right. You need to reconfigure log4net after setting a property.
Here is an example:
using Castle.Core.Logging;
using log4net.Config;
class MyClass {
private readonly IExtendedLogger _extendedLogger;
public MyClass(IExtendedLogger extendedLogger) {
_extendedLogger = extendedLogger;
}
public void MyFunction() {
_extendedlogger.GlobalProperties["logName"] = logName;
XmlConfigurator.Configure();
_extendedlogger.Error("my error message");
}
}
Is there a way to figure out where is Log4J picking the configuration file from?
I tried to change my log4j.xml and the changes were not reflected in Log4j behaviour. I deleted log4j.xml and funnily enough, Log4J is still working with the old behaviour. So it must be picking some configuration file which is available in my namespace. But the question is how can I figure out which one. Is there a way to do that? there are so many different dependencies on jars etc, so one of them must contains a log4j.xml or log4j.properties that is overriding my changes.
Any ideas?
When running your application you can set the system property -Dlog4j.debug. log4j will produce debug output in this case and tells you about how it resolves the path to the log4j.xml, e.g.:
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader#11b86e7.
log4j: Using URL [file:/C:/develop/workspace/foobar/target/classes/log4j.xml] for automatic log4j configuration.
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator
To set a path explicit use the system property -Dlog4j.configuration=file:c:/pathToFile as described here.
Activating -Dlog4j.debug like suggested by FrVaBe in his answer is a good solution. However, I wanted to print or log the location on startup without activating log4j's debug mode. I created a little util method, that is mostly a copy of log4j's default init routine, which returns the URL of the configuration file.
Maybe it's useful for someone else:
/**
* Get the URL of the log4j config file. This is mostly copied from org.apache.log4j.LogManager's default init routine.
*
* #return log4j config url
*/
public static URL getLog4JConfigurationUrl(){
/** Search for the properties file log4j.properties in the CLASSPATH. */
String override = OptionConverter.getSystemProperty(LogManager.DEFAULT_INIT_OVERRIDE_KEY, null);
// if there is no default init override, then get the resource
// specified by the user or the default config file.
if (override == null || "false".equalsIgnoreCase(override)){
String configurationOptionStr = OptionConverter.getSystemProperty(LogManager.DEFAULT_CONFIGURATION_KEY, null);
URL url;
// if the user has not specified the log4j.configuration
// property, we search first for the file "log4j.xml" and then
// "log4j.properties"
if (configurationOptionStr == null){
url = Loader.getResource("log4j.xml");
if (url == null){
url = Loader.getResource(LogManager.DEFAULT_CONFIGURATION_FILE);
}
} else {
try {
url = new URL(configurationOptionStr);
} catch (MalformedURLException ex) {
// so, resource is not a URL:
// attempt to get the resource from the class path
url = Loader.getResource(configurationOptionStr);
}
}
if (url == null)
throw new RuntimeException("log4j configuration could not be found!");
return url;
}
throw new RuntimeException("default init is overridden, log4j configuration could not be found!");
}
PS: if you know a way to ask log4j for it's currently used configuration file, let me know.
I am following this tutorial and I am trying to setup the code in a Event Receiver.
I need 2 properties to send into their method a SPWeb and string.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// is there a way to make this non hardcoded?
SPSite site = new SPSite("http://localhost.com");
SPWeb web = site.OpenWeb("/");
string XMlPath = // get xml file path
CreateGroups(web, path);
}
private void CreateGroups(SPWeb currentSite, string groupsFilename)
{
}
So I tried to use getFullPath but that did not work. I also tried to use MapPath but I did not seem to have access to that.
So how do I get XML file (I think thats what I need)?
You need to dispose of the SPSite / SPWeb object, this is usually done in a using clause.
You don't need to use an absolute path (hard code) in a feature receiver, as the feature is already web/site scoped
your XmlPath usually needs to point to a file on the Sharepoint server, which you also deployed in your Feature - as the feature receiver is running after all the normal files have been deployed, you're good.
Without further ado, slightly different code:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//Web scoped feature?
//spWeb = (SPWeb) properties.Feature.Parent;
//assuming Site scoped feature
spWeb = ((SPSite) properties.Feature.Parent).RootWeb;
using (spWeb)
{
string XmlPath = properties.Definition.RootDirectory + #"\Xmlfile\groups.xml"
CreateGroups(spWeb, XmlPath);
}
}
So how do you get your XML file into "\Xmlfile\groups.xml"? Just create a module! (Add new item > Module)
The elements.xml of your module should look something like this:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="Xmlfile" Path="Xmlfile">
<File Path="groups.xml" Url="Xmlfile/groups.xml" />
</Module>
</Elements>
Of course you will need to add your groups.xml file into that module (Context menu > Add existing item) for this to work.
Also note that you can easily debug feature receivers, just make sure that the deployment configuration is set to "No Activation" (Project Properties > Sharepoint > Active Deployment Configuration) - this way you will need to manually activate the feature on the site (instead of Visual Studio doing it automatically for you in debug mode) - but debugging will work flawlessly.
I have select few places in my application where I'd like to always log values. I could simply use Log.Info() and leave it at that, but I'd prefer a solution that can't be disabled by an accidental change to the level configuration. In this case, as long is log4net is not disabled, I want these log statements to fire.
What's the best approach?
Just looking at some information it looks like one option is to create a custom level with a value set above Emergency, but I don't know if that's a brutally awful hack with side effects I'm not realizing or a legitimate option. I couldn't find any clear guidance in the documentation.
I am not a log4net expert, but something like this might do what you want:
This code will get a named logger from the LogManager and will programmatically set its level to "ALL". If you retrieve this logger later in your code, it will always log, even if the log level is set to OFF in the config file.
To test, set the root log level to "OFF" in the config file, then use the code below:
log4net.ILog log = log4net.LogManager.GetLogger("abc");
log.Info("this won't log because root logger is OFF");
//Reset the level
log4net.Repository.Hierarchy.Logger l = (log4net.Repository.Hierarchy.Logger)log.Logger;
l.Level = l.Hierarchy.LevelMap["ALL"];
//Try to log again
log.Info("this will log because we just reset abc's level to ALL");
I tested it and it does seem to work.
I found this information here and here.