Enterprise Library Logging - How can I prevent the "General Information: 0 :" entry? - enterprise-library

I'm using EntLib 5.0 Logging Application Block. I created a CustomTraceListener and while testing it I noticed that each time I log with Logger.Write() my listener's Write() method is called with
General Information: 0 :
and then the WriteLine() method is called with the expected and desired log content that the TextFormatter produced
I can't figure out why I'm getting that first "General Information: 0 :" message.
Anyone know if that is controlled somewhere in the config?

While investigating why the TextFormatter wasn't being used I read more about custom TraceListener implementations and learned that you need to override the TraceData method as well:
public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
Once I implemented that method the "General Information" messages stopped happening AND my TextFormatter with it's custom template string was being used. All is well!

Related

Can't redirect Trace.WriteLine to Serilog using SerilogTraceListener

In one of my project (.net core 3.1), I need a way to redirect System.Diagnostics.Trace.WriteLine to Serilog file. I found the SerilogTraceListener package which seems to be the right candidate.
Unfortunately until now, I haven't been able to find a way to make it works.
To reproduce it,
1) Create a .net core console project
2) Add the following nuget package : Serilog, SerilogTraceListener, Serilog.Sink.Console, Serilog.Sink.File
3) Overwrite the Program class code by the following
class Program
{
static void Main(string[] args)
{
// Works fine
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("log.txt")
.CreateLogger();
Log.Logger.Information("A string written using Logger.Information");
// Trace is written in the console but not in the file
Trace.Listeners.Add(new ConsoleTraceListener());
Trace.Listeners.Add(new global::SerilogTraceListener.SerilogTraceListener());
System.Diagnostics.Trace.WriteLine("A string written using Trace.WriteLine");
}
}
What am I doing wrong?
TL;DR; You need to set the MinimumLevel to Debug or Verbose in order to see the Trace.WriteLine messages.
SerilogTraceListener maps System.Diagnostic.TraceEventType to Serilog.LogEventLevel, and when you call Trace.WriteLine, it maps these events to the Debug log event level.
That means Serilog's logger is receiving a message of type LogEventLevel.Debug.
The minimum level configured in Serilog by default is Information, which means Debug messages are being suppressed.
You have to configure the MinimumEventLevel to Debug (or Verbose) in order to see the Trace.WriteLine messages:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug() // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.WriteTo.Console()
.WriteTo.File("log.txt")
.CreateLogger();

How to send message by message to Kafka

I'm new to reactive programming and I try to implement a very basic scenario.
I want to send a message to kafka each time a file is dropped to a specific folder.
I think that I don't understand well the basics things... so please could you help me?
So I have a few questions :
What is the difference between smallrye-reactive-messaging and smallrye-reactive-streams-operators ?
I have this simple code :
#Outgoing( "my-topic" )
public PublisherBuilder<Message<MessageWrapper>> generate() {
if(Objects.isNull(currentMessage)){
//currentMessage is an instance variable which is null when I start the application
return ReactiveStreams.of(new MessageWrapper()).map(Message::of);
}
else {
//currentMessage has been correctly set with the file information
LOGGER.info(currentMessage);
return ReactiveStreams.of(currentMessage).map(Message::of);
}
}
When the code goes in the if statement, everything is ok and I got a JSON serialization of my object will null values. However I don't understand why when my code goes to the else statement, nothing goes to the topic? It seems that the .of instructions of the if statement has broke the streams or something like that...
How to keep a continuous streams that 'react' to the new dropped files ? (or other events like HTTP GET request or something like that) ...
If I don't return an instance of PublisherBuilder but an Integer for example, then my kafka topic will be populated by a very huge stream of Integer value. This is why examples are using some intervals when sending messages...
Should I use some CompletationStage or CompletableFuture ? RxJAva2? It's a bit confusing which lib to use (vertx, smallrye, rxjava2, microprofile, ...)
What are the differences between :
ReactiveStreams.fromCompletionStage
ReactiveStreams.fromProcessor
ReactiveStreams.fromPublisher
ReactiveStreams.fromSubscriber
Which one to use on which scenario ?
Thank you very much !
Let's start with the difference between smallrye-reactive-messaging & smallrye-reactive-streams-operators: smallrye-reactive-streams-operators is the same as smallrye-reactive-messaging but in addition it has a support to MicroProfile-context-propagation. Since most reactive-messaging providers use Vert.x behind the scene, it will process your message in an event-loop style, which means it will run in separate thread. Sometimes you need to propagate some ctx from your base thread into the new thread (ex: populating CDI and Tx context to execute some JPA Entity manager logic). Here where ctx propagation help.
For method signatures. You can take a look at the official documentation of SmallRye-reactive-streams sections 3,4 & 5. Each one has a different use case. It is up to you which flavor do you want to use.
When to use what ? If you are not running within reactive context, you can use the below to send messages.
#Inject
#Channel("my-channel")
Emitter emitter;
For Message consumption you can use method signature like this :
#Incoming("channel-2")
public CompletionStage doSomething(Message anEvent)
Or
#Incoming("channel-2")
public void doSomething(String anEvent)
Hope that helps.

How to make EF log sql queries globally?

How do I "tell" EF to log queries globally? I was reading this blog post: EF logging which tells in general how to log sql queries. But I still have a few questions regarding this logger.
Where would I need to place this line context.Database.Log = s =>
logger.Log("EFApp", s);?
Can it be globally set? Or do I have to place it everywhere I do DB
operations?
In the "Failed execution" section, the blogger wrote that, and I
quote:
For commands that fail by throwing an exception, the output contains the message from the exception.
Will this be logged too if I don't use the context.Database.Log?
Whenever you want the context to start logging.
It appears to be done on the context object so it should be done every time you create a new context. You could add this line of code in your constructor though to ensure that it is always enabled.
It will not log if you do not enable the logging.
I don't recommend to use that's functionality, because, it hasn't reason to exists in the real case.
Thats it use a lot of to debug code only. But, wether you wanna know more than details ... access link... https://cmatskas.com/logging-and-tracing-with-entity-framework-6/
In this case you can put code like this
public void Mylog()
{
//Thats a delegate where you can set this property to log using
//delegate type Action, see the code below
context.Database.Log = k=>Console.Write("Any query SQL")
//Or
context.Database.Log = k=>Test("Any query SQL")
}
public void Test(string x){
Console.Write(x)
}
I hope thats useufull

Bulk logging using Enterprise library

Hi i am using Enterprise library 5.0 to log messages in text file, as a part of that i need to log collection of messages to the text file .
Below is the part of code which logs to text file using flatfilelistener
public void LogToFile(string message, string category, IDictionary<string, object> additionalDetail)
{
var logger = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
logger.Write(message, category, 0, 0, TraceEventType.Error, string.Empty, additionalDetail);
}
The above will log single message in text file, like that i will call for each item in collection which i need to log.
So , how to log everything in single stretch? like placing in buffer and updating logfile on single stretch.
I guess there is one property named "AutoFlush" but i don't know how to use that.
using auto flush
That is likely your best bet. Just let the buffer handle it or create a custom flush mechanism that you can call at a specified duration such as the end of a http request or if you are paranoid perhaps when an application crashes and you can't trust autoflush to work.

EventLogInstaller Full Setup with Categories?

It appears the MSDN docs are broken concerning creating an Event Log completely along with a definitions file for messages. I am also lost on how to setup Categories (I have custom numbers in the 3000's for messages).
Can anyone point me to a link or show sample code on how to make this right?
You should start (if you haven't done so already) here:
EventLogInstaller Class (System.Diagnostics)
The sample provided there is the foundation for what you want to do. To sum it up, build a public class inheriting from System.Configuration.Install.Installer in an assembly (could be the same DLL where you have the rest of your application, a separate DLL, or an EXE file), decorate it with the RunInstaller attribute, and add your setup code in the constructor:
using System;
using System.Configuration.Install;
using System.Diagnostics;
using System.ComponentModel;
[RunInstaller(true)]
public class MyEventLogInstaller: Installer
{
private EventLogInstaller myEventLogInstaller;
public MyEventLogInstaller()
{
// Create an instance of an EventLogInstaller.
myEventLogInstaller = new EventLogInstaller();
// Set the source name of the event log.
myEventLogInstaller.Source = "NewLogSource";
// Set the event log that the source writes entries to.
myEventLogInstaller.Log = "MyNewLog";
// Add myEventLogInstaller to the Installer collection.
Installers.Add(myEventLogInstaller);
}
}
When you have your assembly compiled, you may use the InstallUtil tool available through the Visual Studio Command Prompt to run the installer code.
Regarding the message definition file (which includes category definitions), the MSDN documentation for EventLogInstaller.MessageResourceFile mentions that you should create an .mc file, compile it, and add it as a resource to your assembly. Digging around, I found an excellent post which should guide you to the end, here:
C# with .NET - Event Logging (Wayback Machine)