Best way to read error messages from a Log4Net log file - c#

I would like to display the log created by Log4Net on a web page in my admin interface.
Isnt there any methods available in the log4net library to read the error messages from the configured source (textfile or database)? At the moment I am using a database table to log all errors.
If not, there must be some third party libraries available that does this for me?

If you want an elegant solution to collect and search logs using log4net based logging, a syslog daemon like kiwi syslog in combination with log4net local or remote syslog appender would probably be the easiest way to do it. Logging in a database works, but in my opinion logs are of no concern to the application itself and should be kept away from it. For instance a failing database connection would probably not show up if the logs resided solely on the same database.

Related

Publish C# Desktop Application with SQL Server database

I have a Visual Studio project that has different Windows Forms and a SQL Server database attached. I want to install this project on my client computer (others). As I haven't published any project before, can someone guide me in an easy way.
When I tried to publish (installed) this project in my computer (setup file would be created and the application would be installed but) but I get the error shown below while saving update delete data. Please guide me correctly.
You are taking a completely wrong approach here.
Databases are not meant to be installed in client's computer. If you have a client/server app, the database should be located only in your server, and the client will access it/request to write into it by sending requests over a protocol like TCP, which your server will react to.
When you add a database to an app, you provide a connection string and this connection string is related to YOUR instance of the database. If you wanted every client to use a unique DB, you'd need to go over to their computers, install a DBMS, create the database there, then edit the program code to include the connection string for the specific client instance. Obviously this is not a viable option unless the clients you're talking about are just like your immediate family/roommates.
If you intend to provide your clients app with saving/reading data functionality, you'd need to implement it by having the data written into a local file which the program will be able to read from, such as a csv or a tab delimited file. Not through a database. At least not SQL server. If you're completely obligated to use a DB, then think about an embedded, serverless DB like one from SQLite
The reason you're getting that error is because the client's program is trying to look for the database instance that is indicated in the code, but of course, this instance does not exist in the client's computer, so the client cannot reach it to do anything.
Also, please remember to use exception handling. We cannot tell what the exact error was (although it is obvious) because your code is only saying "an unhandled exception happened". Always wrap your code In try/catch blocks and at the very least have them print the exception to a console so that you can know WHY did a program failed on runtime.

Logging web services operations behind load balancer

I developed some web services will be installed on 4 different servers behind a load balancer mantains sessions.
I'm using c# and log4net.
The appenders are a RollingFileAppender and an AdoNetAppender.
I read from https://logging.apache.org/log4net/release/faq.html (section How do I get multiple process to log to the same file?)
If you use RollingFileAppender things become even worse as several
process may try to start rolling the log file concurrently.
RollingFileAppender completely ignores the locking model when rolling
files, rolling files is simply not compatible with this scenario.
I can't use RollingFileAppender with MinimalLock. But I want to log from the different servers to the same file.
I prefer to keep log4net but I'm interested also in other solution (not the linux syslog one). No commercial solutions allowed for costs.
Unfortunately, you'll discover that logging directly to the same file from multiple processes is not a very feasible option.
You have several alternatives:
Log to different files - each server can have a separate file
Send all your logs to one application, which will then log to the files. This will make your logging more brittle and require extra development effort.
Log to a database - databases are designed to have multiple processes writing to them at once
Log to a logging server - Seq, Stackify Retrace, and Azure Application Insights are some examples of solutions that are robust and designed to ingest logs from multiple applications - plus you get much better capabilities

Log4Net offline DB Support

I am developing an asp.net web application and want to log my exceptions into SQL DB. For this I am using Log4Net AdoNetAppender to log info into SQL DB, now the problem occurs when the DB goes offline. Log4Net doesn't persist the log messages. So all messages get lost while the DB was offline, is there any way to retain the messages until the DB comes online and then log all the messages to DB once it become available. Although by using reconnectonerror value="True" it starts logging again when DB is available but all intermediate messages while DB was offline are not logged.
Or there exist any other approach to log exceptions in Db with offline support.
There is nothing with helps you out of the box with this. You can always log to a file (keep the last week or so) and the database. If for some reason there is a gab in the logging you can fallback on the file.
If you want the behavior you describe you can always implement your own appender. Let is inherrit from the adonetappender and add your failover code. However keep in mind that you do not want to create an appender which eat all your memory...

How to handle application configuration and data?

Microsofts preferred way to handle application configuration and runtime data seems obvious at a first glance: App.config, which will be stored in the application execution directory (C:\Program Files\ProductLocation in most cases.) where only privileged users have write access. (Makes sense to me, because a casual user shouldn't be able to alter essential application configurations).
For normal user configuration, there's a user.config which will be copied into each users personal application data directory (%APPDATA%).
But this leads to a few questions:
How can I alter configurations for every user without executing the process as administrator?
Where should I store application data that doesn't get deployed with the application, instead should be generated when the application is started the first time?
How is it possible to have e.g. dynamic connections strings, like for a database health monitor application?
I checked out the program data folder (%PROGRAMDATA% -> C:\ProgramData), but it seems this place is read-only for the standard user. (Windows Installer does create folders in here if needed, but they're all read-only.) -> What happend to %ALLUSERS%?
Example where the Microsoft way may fail in my eyes:
A financial application where every user should store his information in the same database (a SqlCE file db), where as the application has to run with user privileges (I don't want to be administrator to manage my wallet). The application needs connection to a database that isn't available at runtime and may be generated in during the first run using EntityFramework. So it could be possible that even the connection string has to be dynamic, and not configured in the app.settings where such information is fixed.
This is stupid! Users could read sensitive information from other users by directly accessing the file database!
-> Security is not only a file permission thing, there could also be database users, certificates, cryptography etc.)
Do I have to develop my own settings handler as a workaround to the Microsoft intended way?
I guess this question is asked a numerous times on SO, but every answer I found showed up workarounds, different solutions. Questions regarding "best practice" are closed immediately, so I tried to provide a practical example here.

c# protect a database connection string in Settings prevent Decompiling?

Is there anyway to prevent people from using Reflector.net to decompile my .exe c# application? I know there is a tons of post about this but I don't really care if people can see my code the only thing I want to "hide" is my database connection string.
I am currently using "Settings" in my c# to keep the database connection's info.
I wanted to know if using those string in my project's Settings would prevent people from seeing it ?
I am using DotFuscator in visual studio 2008 but I heard it wasn't preventing people from decompiling my program.
I know I could use a Web Services but my server will be on linux so I guess I can't store web services on Linux.
No. Even if you encrypt the connection string in the program code or in a settings file, you will need to decrypt it, and the program must necessarily contain the decryption key somewhere, which means that someone who is interested enough in finding it will find it, no matter how creative you are in hiding it. Why do you need to hide the connection string? If you are afraid that someone who has your program might call the web services directly and trigger unintended actions, you should look into how the web services are structured, what they allow clients to do, and how the authorization works, and make security improvements there instead.
If your program has the connection string in it, users of your program can get it back out. Even if you encrypt it, they can sniff it when your program connects to the DB server.
If you don't want your users to know your DB login credentials, don't give your DB login credentials to the users. That's the only way.
You could do this by instead giving each user their own credentials, and using the permissions system in the DB server to control what they can or can not do.
As others have stated obfuscation is no real protection for a connection string stored in a client application where the user have access to the binaries.
Don't use a direct database connection from your program unless the user is trusted to use the database directly with the same privileges. Have a service (web service, REST-service, etc) in between that you host on your own server. Linux can host services of any of those types I mentioned (use Mono if you want them in .NET on Linux)
In order to expose your database via a web service using Mono or any other language/framework you can host on Linux you would create a web service method for each atomic operation you want to perform against the database.
An additional advantage over letting the client application access the database directly is that when the client application is using a service between itself and the database you are free to change your data store without affecting the client. You can decide to change the database schema in your database or replace the database with a NOSQL solution or even a flat file.
Having a service instead of communicating directly with the database moves the authentication/authorization requirement one step, so now you need to implement it in the service. Fortunately there is rich support for authentication in a web service.
Take a look at this guide on this specific topic from MSDN. Keep in mind, however that this only shifts the security burned. Now you need to manage the security of the key

Categories