What defines the set of appenders that a Log4j version 1 logger "contains"? - log4j

I'm trying to read some Log4j v1 code in order to update it to Log4j v2, and I've found something I can't resolve from the documentation.
The issue is the Logger.getAllAppenders() method. The documentation, linked, says that the method "Get[s] the appenders contained in this category as an Enumeration." There is no definition of what it means for an appender to be "contained in" a category there, however, and I can't find a definition anywhere else in the documentation. Thus, I'm unable to predict exactly what the method will return.
As precisely as possible, what defines the set of appenders that are "contained in" a category like a logger? In particular, does a child logger contain appenders assigned to its parent? Does a parent logger contain appenders assigned to its child?
Answers that explain the basis of your knowledge, like links to documentation that I missed, are especially appreciated.

For end-of-life software like Log4j 1.x, the best documentation is the source code (which will never change).
Category.getAllAppenders() returns the list of appenders directly linked to the given Logger (cf. source code) and does not include the appenders of parent loggers. Hence it is a subset of the appenders that will be used by that logger.

Related

Log4Net: Enumerating GlobalContext properties?

I'm trying to utilize the Loggly appender utility for log4net.
I've found that their code is enumerating through the ThreadContext properties and appending them to the payload getting sent over the wire to the loggly service. Good idea! However, the same feature is not being applied to the GlobalContext properties. Figuring this was a miss on their part I tried my hand at enumerating through the GlobalContext properties and adding these to the payload as well.
However, this has proven to be a problem. There doesn't appear to be any way to access the keys and associated values as the ThreadContext properties are accessed.
How can the GlobalContext properties be enumerated?
The only way I see would be to retrieve the properties class for the global context (GlobalContext.Properties which returns a GlobalContextProperties class) and get the ReadOnlyPropertiesDictionary returned by the internal method GetReadOnlyProperties() through reflection. Once you have the ReadOnlyPropertiesDictionary you can iterate on keys and values
From what I see the ThreadContext has more or less the same mechanism so you could take example on the ThreadContext enumeration to port it to the GlobalContext.

Customize DataService namespace and EntityContainer

Nutshell: The Entity Framework Provider for WCF Data Services pulls the schema namespace and EntityContainer name directly from the namespace and class name of the DbContext, respectively. This is also true for DbContexts that are developed using the code-first method.
Is there a way to modify this provider behavior a posteriori--that is, without modifying the class name or the EDM(X)?
Background/caveats/opinion: This is a handy behavior for prototyping, but in a production scenario, the class name is itself an implementation detail that should be hidden from service consumers.
Further, in my case the name cannot be changed, since I am using a framework that provides a very generic DbContext that I am then composing/extending.
Note that I am not discussing a way to create more "space" between the CLR and EDM representations of the data model. Rather, I'm looking for a way to modify the behavior of the DataService<T> extension itself, so that the internal CLR namespace and DbContext extension class name (preserved in the EDM, which is totally okay) aren't exposed externally.
The specific customization points in the service metadata (custom-ns and custom-container below):
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="<custom-ns>" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityType Name="EgEntity">
.
.
.
</EntityType>
.
.
.
<EntityContainer Name="<custom-container>" m:IsDefaultEntityContainer="true">
<EntitySet Name="EgEntity" EntityType="<custom-ns>.EgEntity" />
.
.
.
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
In code-first, you can specify the schema for tables in the SSDL with the Table annotation (look at the Schema property). Unfortunately, I don't think you can overwrite the schema namespaces used in the CSDL with either attributes or the model builder (please note that I haven't extensively researched this).
You may attempt to play with namespace aliases, although I'm not sure this would work as you intend.
In model-first and database-first, see this question which seems to answer yours. Let me know if it doesn't.
I realize this answer is not too helpful, but I would like to suggest that you specify proper namespaces for your codebase, even (especially) for production. This is because I can't immediately see why a namespace should be "hidden" in any normal scenario, but please do expand on your use-case if you disagree.
That being said, I agree that one should be able to map proper CLR namespaces to different EDM schemas for other reasons, I guess everybody is OK with using the same names as long as they make sense. By the way, don't forget vendor prefixes, especially since you're exposing these names to the network.
Note that the third-party framework namespace shouldn't be relevant as long as the context class is not sealed. Usually, entities are defined as POCOs so that's normally not a problem either. Thus, the standard solution would be to extend this generic context class in a namespace of your own, along with the entities.

log4net programmatically set appender

I want to have log4net write to one file for debug messages and another for all other messages and I want to set this all up programatically. I can see how to specify the lower limit of an appender but no the upper limit (ie prevent the debug appender from writing messages above debug level).
Is there a way to do this?
You can do this with:
Hierarchy hierarchy =
(Hierarchy)LogManager.GetRepository();
hierarchy.Root.AddAppender(appender);
where appender is of type IAppender

JAXB : Is the annotation #XmlAccessorType is only for Serialization and nothing to do with Binding of data?

I wanted to know why do we need to specify the Annotation #XmlAccessorType when working with JAXB .
When i googled for this i found out this description from a website stating this
#XmlAccessorType sets default field and property serializability. By default, JAXB serializes public fields and properties. By setting #XmlAccessorType, the bean can choose to only allow annotated fields to be serialized.
Here the author mentions that with this annotation it gives control on serialization .
My question is , so #XmlAccessorType has nothing to do with the JAXB Binding and Unbinding from XML to java and java to XML , and it is all about Serialization only .
JAXB's #XmlAccessorType annotation is only used by JAXB (JSR-222) implementations for determining how to marshal a file to/from XML:
Normally the main decision to be made is between FIELD & PROPERTY/PUBLIC. FIELD is particularly useful when you have logic in your get/set methods that you do not want triggered during marshalling/unmarshalling. To see one way this choice affects the mapping metadata see:
http://blog.bdoughan.com/2012/02/jaxbs-xmltype-and-proporder.html
NONE is a useful choice when you have many unmapped properties and you want to tell your JAXB implementation to only map the fields/properties you have annotated. This can be alot easier than adding a lot of #XmlTransient annotations into your model.
Fore More Information
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html

JAXB marshaling: how to include exceptions info into xml output file?

I have a very basic application that uses JAXB marshaller to validate input information against an xsd schema. I register a validation event handler to obtain information about the exceptions. What I would like to achieve is the ability to include this information into xml output structure I receive as a result of marshaling. I’ve included exception collection section into my xsd and now I can instantiate the corresponding exception object once an exception is encountered. The question is how do I attach this object to the rest of my JAXB generated Java objects structure considering the fact that marshaling process had already started? Is it even possible? Or should I try and modify the xml result after the marshaling is done? Any advice would be highly appreciated.
Thanks!
There a couple of ways to do this:
Option #1 - Add an "exceptions" Property to You Root Object
Ensure that the exceptions property is marshalled last, this can be configured using propOrder on the #XmlType annotation.
Create a validation handler that holds onto the root object.
When the validation handler encounters an exception, add that exception to the exceptions property on the root object.
Option #2 - Use an XMLStreamWriter
Create an XMLStreamWriter
Write out a root element
Set the validation handler on the marshaller, ensure that it will store the exceptions encountered.
Marshal the root object to the XMLStreamWriter.
Marshal the individual exceptions encountered to the XMLStreamWriter.
Write out the close for the root element.
Short answer: no. JAXB is intended to take an object graph and produce XML. it's not intended to do this.
Longer answer: You could inject the exception representation into the graph after JAXB is done the first time.
Even longer answer: There are a number of plugin and customization technologies for JAX-B, and it's possible that you could use one of them. However, it's very hard to conceptualize this at the abstract level of your question.

Resources