How to create reusable a semantic logging library? - c#

I am currently in the process of designing a .net logging library that could potentially be used across different solutions in our organisation as a nuget package. However, I also want to make sure that we do semantic logging so that the logs are still structured.
Example -
CustomEventSource.Log.OrderProcessingFailed(order.OrderNumber, order.ItemCount);
Given that I am creating a shared service that is application agnostic, it shouldn't be tightly coupled to the application. Here is an example flow.
Developer creates application and downloads logging package
Developer creates EventsIds (e.g. OrderProcessingFailed), categories, keywords etc... specific to
their application
Developer creates instance of logging component
passing details like machine name, event source name.
Developer
creates logs using logging instance passing details created in step
2 AND an array of name value parameters that are relevant (e.g OrderNumber: 1234, ItemCount: 3).
Logging library writes the events in ETW.
External listeners captures the events.
Has anyone seen a solution resembling above? My question is more on how to implement step 2 above. I don't want EventId to be free text but it should be something that the client is "forced" to implement similar to how an interface gives you an idea of how to implement what is required.
I know my question is a bit vague at this point so clarifications are welcome.

Related

log4 net multiple loggers vs single logger in an application?

We have c# application with several different modules. We are using log4net for logging. What should be done to log the messages:
Create a centralized logging project: The application classes to use centralized logging project's dll's static methods to log the messages. So, no class in application creates the logger, all logging requirements to be fulfilled by this dll OR
All types in the application itself creating their own loggers: Easy to check which type generates which message, easy to manage different type of logging requirements i.e.we can throttle logging behavior of each type independently, like one class logging ALL logs but other only loggin ERROR.
What is the preferred practise?
The approach2 has its own benefit but approach1 looks clean as each class would no longer be responsible for calling "GetLogger(typeOf(className))".
What is the recommended way?
It really depends on the usecase, when making a library it can make sense to use method 1. However when making a complex program method 2 will help you to manage different logger independently. Method 2 will give the also the option to log all in you project like method 1 does. However method 1 does not support differing on logger. So method 2 seems a better choice in most cases.

jBPM custom authorization

I am trying to use in jBPM users from existing ASP .NET MVC Web Site.
As I understand from docs and this forum topics (first, second) best solution would be implementing of UserGroupInfoProducer that will call external service. But due lacking of experience with java I faced with several problems.
First approach: Create project with required implementation, deploy it and config jBMP to use it.
Problem was in implement interfaces that declared in another project, I've tried to add maven dependencies but after failing with some classes I've just added reference to required jar.
Deploy it on jboss like war failed, deploying like jar succeeded but server did not find UserGroupInfoProducer and other implemented interfaces.
Another problem in changing config of jbmp-console. Only way that I've found for that is modify archive directly, but I don't this it's right solution.
Second approach: Create own package of jBPM with required classes.
Problem here that I don't know what repository use for this and how to build version for my server.
As I understand from this link I need to use jbmp-console-ng, only maven task for creating war package that I found was in jbpm-console-ng-showcase I've tried to run it (release 6.2.0 Final) on:
On Windows: failed to execute because of maven error about long path, after migrating project to gradle and excluding dependencies on jmxtools-1.2.1.jar and jmxri-1.2.1.jar it created war but jboss failed to start service.
On Mac and Ubuntu using virtual box: it required to downgrade java to 1.6 and built war after this, but it failed to deploy due duplication of some classes.
As I understand you need to build diferently for each version of server but I don't know how to do this.
Third approach: Create come simulation of supported authorization ways. As I understand jBMP support LDAP, JAAS, database and file. Database and files will require duplicating users so I researched about simulating LDAP or JAAS (preferably using C#) but did not find any acceptable way.
I will be very grateful for any advise which of this approach may work or some other suggestions. Especially about building war of jbmp-console.
version used:
jBPM(6.2.0 Final), jBoss(Wildfly 8.1.0 Final), Java(1.8.0.73), Ant(1.9.6), Gradle(2.11), Intellij IDEA (15.0.3).
After a few weeks of try and error approach I have finally managed to provide fully custom authorization module for JBPM suite ( kid-wb, server and dashbuilder ) in our application. It wasn't easy and required some magic - overwriting two classes won't do it :)
My requirements was quite complex and final solution consist of kie-wb, server, dashbuiler and external authentication which provide by REST Web Service response users with roles based on token passed in session. Another thing that you have to keep in mind is that kie-wb and server are communicating through BASIC authentication - if you want to use server also you have to provide two possible methods of authentication. I won't be able to publish here any code, because it is not an open source project, but I will try to help the best I can.
If you are using WildFly as you are saying above, what you should look at is Undertow Servlet Extension
Overwriting handleDeployment method allow you to write your own IdentityManager( if you need one ) and register your custom AuthenticationMechanism.
To implement your own AuthenticationMechanism you should look at this project Custom Spnego Auth for WildFly
My solution was based on mentioned above project - you don't have to implement every class - in my case writing my own class implementing AuthenticationMechanism was sufficient to get custom authentication working in kie-wb ( not for server though).
So if you already have overwritten Servlet Extension ( and registered by putting file io.undertow.servlet.ServletExtension containing your custom servlet extension class name inside /WEB-INF/classes/META-INF/services/ path of .war file ) and implemented custom AuthenticationMechanism next thing you should do is write class implementing org.jboss.security.auth.spi.LoginModule interface. If you don't want to implement this interface all by yourself you can just extend one of already implemented classes from WildFly - for example UsernamePasswordLoginModule or other.
To let WildFly know that we are using non-standard Login module we have to modify standalone-full.xml as follows:
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="com.package.CustomAuth" flag="required">
</login-module>
</authentication>
</security-domain>
</security-domains>
</subsystem>
and then...we are almost done :) One thing left to do is to modify deployment descriptor inside .war file. We have to change web.xml inside /WEB-INF dir as follows:
<login-config>
<auth-method>BASIC?silent=true,CUSTOM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login_failed.jsp</form-error-page>
</form-login-config>
</login-config>
CUSTOM is name of your authentication mechanism that was registered inside class implementing Servlet Extension class.
Above instruction does not cover kie-wb <-> kie server communication. This matter was more complex and required a few workarounds. As I said before I won't be able to provide full solution with more detailed examples, but feel free to ask me anything refering this case.

Substituting a WSDL Interface

I've been handed a project that needs some work doing and the original team that created it have all since left the company. This has been sat "on-the-shelf" for 4 years and everyone but our client had forgotten about it. They want it delivering now and it doesn't work.
The system is a relatively simple ASP Web Forms application for submitting data to another service via 2 WSDL interfaces, logging that request in a SQL database and submitting the response to another service via OPC.
I can set up all of those interfaces for testing except the WSDL. I just have the software here to run. Is there any way I can easily create a service to simulate the final one so I can test my software. I only have the 2 WSDL files to go on. These aren't complicated services. I'm only using 4 methods total.
I've been led to believe that the original creator of this system did something similar but I can't find what he used or any documentation about it. I expect it was run on his laptop and was lost when he left the company.
The WCF service client should be wrapped and exposed via an interface to your software. That way, you can mock the interface and test how your software responds to various inputs/outputs from the mocked service client. You control all aspects of what is returned, including potentially throwing exceptions as the real WCF service client would.
This is basically the reason why the "I" in SOLID exists - because substitution of implementation based on interface is simple to do.

How to use Azure Mobile Services practically (cross-platform client)?

Azure Mobile seems to be very useful having built-in common functions so I don't have to implement them myself. But still I can't understand how can use it if I need something more than the very simple example with ToDoItems. First of all TableController by one hand seems to be very useful 'cause it can provide persistent server features and client notification feautures. By other hand I can't understand how the example can be used for real mobile devices if the ToDoItem class is in the back-end assembly (of course I would like to include it in a mobile application). But if I use some shared assembly that has to be portable how can I implement ITableData if it is not in the portable subset? What is the way to use MobileServiceCollection with CollectionChanged event in some real project? Then the problem is how to implement the logic layer - the persitent mode with DbContext is good, but sometimes I need some more logical features on the server than just a storage. Scheduled jobs seem to don't suite cause I need to invoke some data processing by client data update but not by some schedule.
If somebody knows how to use Azure Mobile Services for a real project please give me some examples/ideas how a portable service layer for mobile applications can interact with Azure Mobile Services backend. For the client applications I use Xamarin tools.
Utilising Xamarin means you can work entirely in C# so you can re-use many concepts you would know from developing C# solutions on non-mobile platforms. For instance, you can share "DTOs" which means you can share code amongst all your platforms. See: http://blog.siliconvalve.com/2013/08/16/portable-azure-mobile-services-dtos-when-using-xamarin-and-c/
I presented at TechEd Australia last year on this and the sample code is available on Github also. A video of the talk and the sample link can be found here: http://blog.siliconvalve.com/2013/09/08/teched-demo-video-available-online/.
At launch mobile services utilised Node.js for server-side functionality (it is still supported) and it is now possible to develop server-side scripts using C# as well. These aren't limited to just database interactions (though these tend to be the examples used). If you look at my sample project you'll see I do some parsing of inbound data to fire off push notifications.
Ultimately there's no easy answer other than to start working with the code (you an run an Azure trial for free for a short period - more than enough to get familiar with the environment).
TableController is only supposed to provide a REST API for one type of entity. At the root, REST is simple. You've got ToDoList, ToDoListItem and maybe for each ToDoListItem you have multiple ToDoListListItemDetail entries. This represents a one-to-many relationship between 3 entities.
Generated Table controllers only deal with one entity so scaffolding will create a ToDoListController for ToDoList entity, a ToDoListItemController for ToDoListItem and a ToDoListItemDetailController for ToDoListItemDetail entity. But all of the entities that you have defined in your web app share the same Context and thus all of them can be queried in any of the controllers. So while by default you can only do GET /tables/ToDoListItem which will give you all ToDoListItems or you can do GET /tables/ToDoListItem/{key} which will give you a specific ToDoListItem matching the key, you cannot get a ToDoListItem that matches a specific ToDoList.
As per REST best practices, such retrieval would be accomplished with GET /tables/ToDoList/{key}/ToDoListItem which would provide all ToDoListItems associated with a specific ToDoList identified by the key. Now this belongs logically to the ToDoListController and in order to expand the controller to get this, you need to implement attribute based routing.
[RoutePrefix("tables/todolist")]
public class ToDoListController : TableController<DataObjects.ToDoList>
{
...
// extended endpoint
// GET tables/todolist/{key}/todolistitem
[Route("{id:guid}/todolistitem")]
public IQueryable<DataObjects.ToDoListItem> GetAllToDoListItemsForToDoList(string id)
{
return from l in Context.ToDoLists
join li in Context.ToDoListItems on l.Id equals li.ToDoListId
where l.Id.Equals(id)
select li;
}
So now using this technique, you can query for whatever you want beyond basic entities provided by scaffolded Table controllers.
Now since you web API back end has to have it DataObject classes inherit from EntityData, you may not be able to reuse them entirely in your Xamarin app. Your Xamarin app layer does not have to implement all data elements of EntityData either - probably only Id and Version. But even if you had to duplicate the definition of your DataObjects (back-end) or DTOs/Models (client) its very small duplication.
If you need to call end points unrelated to table storage, you can invoke custom API as described in the Work with a custom API section of this article (https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-dotnet-how-to-use-client-library#work-with-tables).
I am not sure if I answered some of your questions or not so please provide more detail.

Error logging sample project

I need to create a Error logging project from scratch in C#.
I would like to save to a file with several levels, this logging project I am taking as an assignment from which I can learn many things and want to build it as small loggin utility for now.
I saw few loggin project which has singleton pattern and a config file having some entries and also in the consuming application config - some references of logger proj interface are there
can some one please give me an idea as how can I create a new logger
proj from scratch and what is the purpose of having entries in
config ?
pseudo code for logger project or any link
Thanks in advance.
Instead of implementing your own logging mechanism you may want to check whether existing components are an option. For example log4net is a frequently used framework that people use for .NET based projects.
Also, the Logging Application Block from Microsoft:
http://msdn.microsoft.com/en-us/library/ff632023.aspx
http://msdn.microsoft.com/en-us/library/ff664569(v=PandP.50).aspx
There are several key elements you need to consider before making one from scratch. Just to name what comes to my head :
How do you want to log? Do you want to save logs to a file, in a database, to send mails, just to have the logs shown in a console?
If you persist the logs, do you want to log everything, forever, or you want a "rolling" X lines to be kept, the rest discarded?
Do you want to have several level of logs? For example, you could log some things Info, Warning, Error, Critical Error, etc.
Do you want your logging library to support custom formatting for the logs?
As for the question about the config, it's really something you want to do. If you're talking about the app.config files, it allows you to can change the configuration of your application without rebuilding it. It can also provide some default parameters the user can override. By user, I mean another developer using your library.

Categories