|
Hi all,
I want to know what is the effective to way to write logs in web service. I personally feel that we should log this to flat files instead of database using Trace Listener.
Writing a snippet for logging is not a big deal, but calling that method classes is bit laborous.
I am bit worry for the following queries.
1. Do I need to write log (calling function to write log) after each line in all the method.
2. If I enable logging level 1,2,3 etc (class level, method level & line level) how do I write a log.
3. What would be the content of log so that I can track the exact error / warning / info.
Can anybody flow their knowledge / opennion ?
s
|
|
|
|
|
Hi,
This is just a suggestion to use Log4Net for tracing purpose
Link :- Log4Net
Hope this helps !!
|
|
|
|
|
manishchourasia2000 wrote: I want to know what is the effective to way to write logs in web service
Effective is a loaded word. If you have specifics objective requirements then you should determine what those are first.
manishchourasia2000 wrote: I personally feel that we should log this to flat files instead of database using Trace Listener
First, you might want to define exactly what "log" means.
My criteria
- I differentiated between 'development' logs and 'business' logs.
- Development logs are solely and completely intended to help developers debug problems that occurred during production.
- Development logs are NOT intended to be 'easy' tools for IT or support to figure out problems. Logs can exist for those purposes but those are business logs (a type of business log.)
- IT and support are welcome to use development logs and can make suggestions for either adding or removing content but they do not dictate it.
- Development logs are NOT intended to provide support for developing code. A developer might use it when actually doing the development but what remains in the delivered code must be suited for use in production. And example of this that logs can not have things like "Now in the loop" or print out every time a polling loop is entered.
- Failures in the development logs cannot stop the business functionality from running.
- Business logs should be handled like any other business requirement where a product owner delivers requirements for it, development implements it, and QA validates it. Failure to write a business log can stop business functionality. That should be specified as part of the requirements
A business log(s) might include things like the following
- A user logged in
- A user deleted a record
- The IP a user request came from.
- Expected errors which are not reported via other mechanisms.
Finally a log cannot exist solely in a database because writing to the database might fail
manishchourasia2000 wrote: Writing a snippet for logging is not a big deal
Use a 3rd party library. As per the other response for Log4net or I have used NLog. You might want to actually research logging libraries. One criteria I used the last time was how active the log library updates were. At least when I looked years ago log4net was not being actively maintained while NLog was. That could have changed.
manishchourasia2000 wrote: I am bit worry for the following queries.
Do not attempt to log too much.
- It provides no benefit.
- It complicates maintenance
- The sheer volume becomes a problem because it takes space
- Because it takes space an inclination develops to get rid of the 'old' stuff which might be needed later.
- The volume makes it hard to find actual problems.
A developer must determine critical points in the application and the log appropriately for those points. Some examples
- Complex Database operations, logging attributes of those.
- Database exceptions
- Exceptions from any external sources such as Rest/Http calls. External system calls should ALWAYS be wrapped in exception handles and exceptions handled.
- Successful/unsuccessful jobs that run at large intervals. Like once a day. But not once a second.
- Major operations that end in expected failures.
- Requests into the system and Responses to those requests.
Security concerns should be address in the above as, for example, logging a password/hash should never occur.
Unexpected exceptions are always something to log. But
- Avoid logging expected exceptions. They are after expected.
- Do not double log exceptions. That happens when someone logs it then throws the same exception again. Either log it and handle it or do not catch it in the first place
Naturally you should ALWAYS catch all unexpected exceptions and attempt to log them somewhere.
|
|
|
|
|
{
private void textBox1_TextChanged(object sender, EventArgs e)
{
_titleText = textBox1.Text;
this.titleChanged += new TitleChangedHAndler(UserControl2.onTitleChanged);
if (titleChanged != null)
{
titleChanged(_titleText);
}
}
}
private void paint(object sender, PaintEventArgs e)
{
drawString(Text,...);
}
public void onTitleChanged(text)
{
Text = text;
this.Invalidate();
}
above code could not call the paint on Invalidate.
UserControl1 and UserControl2 are the 2 usercontrol added on the main form within the spiltcontainer
I have used the spiltcontainer to add the user control
modified 27-Mar-15 0:41am.
|
|
|
|
|
Well...yes it does.
It just does it on Control1, not Control2.
Just becasue you can execute a method from Control2 doesn't mean that it executes on a Control2 instance - it's just a method which is called. the value of this isn't going to magically change to the correct instance of Control2 just because you called a method in it's class.
Seriously, You need to stop, take a step back and get instances and suchlike straight in your head - because this doesn't look like you are trying to do anything sensible.
As I think I have already explained to you, neither control should know about the other - only the containing control / form should do that.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Have a look at this: https://www.dropbox.com/s/6qrtt5g9340kptv/TwoControlsDemo.zip?dl=0[^] It's a little demo I threw together for you to show you how to get two controls talking properly.
At the moment you seem to be trying to code by guesswork, and that isn't going to work...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I need a suggestion, how to do scheduling in c# without using timer class as it takes memory. Though it does not an issue if timer is used in efficient manner, but i am in need of long time scheduling process. So please share the suggestions for scheduling without use of timers.
|
|
|
|
|
In the past, I have used Monitors quite successfully to handle scheduling. Basically, you get the time that you need to next run, take away the current time to give you an interval that you need to sleep, and then use this with a Monitor.Wait to wait for that length of time. The reason for using Monitor.Wait rather than Thread.Sleep is that you can easily pulse your monitors if you need to wake them early, e.g. if you want to cancel the operations. Note that a timer or a monitor are no guarantee that an operation will happen exactly at a certain time, only that it will happen on or after that point in time.
It goes without saying that these tasks should operate on a background thread.
|
|
|
|
|
I'm stuck in this quandary on whether or not to redesign the underlying classes for an application that is almost ready to go live (currently in user testing). This is by-the-way where I spend a great deal of my time, in a quandary that is. I've already searched for alternatives, Google, CP, Stack Overflow, etc., with minimal hits where actual discussion had occurred.
But first, some important background information. Where I work virtually all of our Windows applications are for internal use. To help with this we wrote a "menu" application that is used to load all of the other application, which in turn are compiled as dlls.
This has worked fairly well, except the dlls are never unloaded from memory when the user closes the secondary application. These dlls are loaded in a fairly straightforward manner.
Assembly myDLL = Assembly.LoadFrom(baseURL + dbDllName);
With an eventual myForm.Show() to display the secondary application's starting form.
I have several forms in my application and I've used a singleton design, http://csharpindepth.com/Articles/General/Singleton.aspx#lazy[^], for the main class that handles database calls, etc. This is so I don't have to pass an instance of the class around to multiple forms.
The downside to using the singleton with an application loaded by our menu application is there is no limitation on how many instances of my application the user can load. This of course can lead to strange behavior to say the least. For example, performing a search in the first application instance updates the grids in all instances.
Now, finally to my question. What are my options other than the two already mentioned, leave it as is and tell the user to not load more than one instance (seems highly unprofessional), remove the singleton and pass an instance of the first instance of the class to the other four forms (not my favorite thing to do). I'm not up on all the latest design patterns so any pointers would be helpful.
|
|
|
|
|
Seems to me that if your shell application is a singleton and cleans up when the children are closed then there should be no orphans.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
To be honest, it sounds to me like you need to investigate hosting each separate application in its own AppDomain. Just tear down the domain when the app needs to be unloaded. This Will also give you the ability to remove issues surrounding strange behaviour due to sharing the same assemblies.
|
|
|
|
|
I'm assuming you are referring to changing how the menu application loads the secondary apps. Unfortunately, I do not have any control over that code. And the last time I made a suggestion to change how the menu works, I got the distinct impression they felt I was attempting to pee in the office coffee pot.
|
|
|
|
|
SteveJD wrote: This has worked fairly well, except the dlls are never unloaded from memory...For example, performing a search in the first application instance updates the grids in all instances.
This is a design problem and not a dll problem.
Normally the only primary reason to unload a dll is because you need to load a new version of the dll without restarting the application.
Yours is problem in the design - probably because you are using singletons. Simple solution is don't use singletons. Each user has their own set of instances of the classes. There is no data overlap.
SteveJD wrote: I'm not up on all the latest design patterns
General consensus is that one shouldn't use Singletons...ever.
I wouldn't go that far as sometimes the appearance of a singleton can be an effective way to manage access to some resource. But there should be very few of them in the application and of course they would need to be usable by many threads at the same time (thus there could not be a problem as you are having.)
|
|
|
|
|
I am currently working on some settings for an application, but I have an annoying problem. I decided to store the settings in a .xml file and then read the values when loading the settings etc. Whenever the settings form is opened, the application will check the values stored in the .xml file and check a specific value is set to "true" or "false". I have a combobox and when you check this combobox, the application will ask you where you want to save the logs using FolderBrowserDialog. If you choose a folder then it will close, you can click the "Save" button and it will work. If you click on "Cancel" then the FolderBrowserDialog window will close and the checkbox will be unchecked automatically. The problem I am facing is that if you check the combobox, click the save button (which changes the value from "false" to "true"), exit the settings and then open the settings form then it will open the FolderBrowserDialog again. This is because the element, which in this case is called "<save_logs>", is set to true.
So my question to you is how can I fix this?
Combobox code
private void Save_log_CheckedChanged(object sender, EventArgs e)
{
if (Save_logs_checkbox.Checked && path_selected == false)
{
Save_logs_combobox.Enabled = true;
var fbd = new FolderBrowserDialog();
switch (fbd.ShowDialog())
{
case DialogResult.OK:
XmlHandler.Edit("//Other/Save_logs_path", fbd.SelectedPath);
path_selected = true;
break;
case DialogResult.Cancel:
Save_logs_checkbox.Checked = false;
Save_logs_combobox.Enabled = false;
break;
}
}
else if (Save_logs_checkbox.Checked && path_selected)
Save_logs_combobox.Enabled = true;
else
Save_logs_combobox.Enabled = false;
}
XML
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Settings>
<Shortcuts>
<Copy_shortcuts>
<Shortcut_1>CTRL+ALT+1</Shortcut_1>
<Shortcut_2>CTRL+ALT+2</Shortcut_2>
<Shortcut_3>CTRL+ALT+3</Shortcut_3>
<Shortcut_4>CTRL+ALT+4</Shortcut_4>
<Shortcut_5>CTRL+ALT+5</Shortcut_5>
<Shortcut_6>CTRL+ALT+6</Shortcut_6>
<Shortcut_7>CTRL+ALT+7</Shortcut_7>
<Shortcut_8>CTRL+ALT+8</Shortcut_8>
<Shortcut_9>CTRL+ALT+9</Shortcut_9>
<Shortcut_10>CTRL+ALT+10</Shortcut_10>
</Copy_shortcuts>
<Paste_shortcuts>
<Shortcut_1>CTRL+SHIFT+1</Shortcut_1>
<Shortcut_2>CTRL+SHIFT+2</Shortcut_2>
<Shortcut_3>CTRL+SHIFT+3</Shortcut_3>
<Shortcut_4>CTRL+SHIFT+4</Shortcut_4>
<Shortcut_5>CTRL+SHIFT+5</Shortcut_5>
<Shortcut_6>CTRL+SHIFT+6</Shortcut_6>
<Shortcut_7>CTRL+SHIFT+7</Shortcut_7>
<Shortcut_8>CTRL+SHIFT+8</Shortcut_8>
<Shortcut_9>CTRL+SHIFT+9</Shortcut_9>
<Shortcut_10>CTRL+SHIFT+10</Shortcut_10>
</Paste_shortcuts>
<Other>
<Windows_start>false</Windows_start>
<Notifications>true</Notifications>
<Save_logs>false</Save_logs>
<Save_logs_path>C:\Users\UserHere\Desktop\Folder</Save_logs_path>
<Save_logs_as>txt</Save_logs_as>
</Other>
</Shortcuts>
</Settings>
|
|
|
|
|
You need a flag. It is only set when you change something about the log save location. Open the dialog when that flag is set. You never save the state of the flag and so it will not be set on form open and the dialog won't open. If you change the Saved Log location then set the flag and open the dialog.
Jack of all trades, master of none, though often times better than master of one.
|
|
|
|
|
Ron Nicholson wrote: You need a flag
Every time I see that I think of this[^].
|
|
|
|
|
I am afraid that I do not understand what you mean. Could you elaborate and/or perhaps give an example?
|
|
|
|
|
I've looked at your code again and I have a question.
if (Save_logs_checkbox.Checked && path_selected == false)
{
Save_logs_combobox.Enabled = true;
Apparently when this function is called, your path_selected is actually set to false. Is that true? If so then maybe you set path_selected to true before you set Save_logs_checkbox.checked to true.
All that said, I'd change the if statement to:
if ((Save_logs_checkbox.Checked) && (path_selected == false))
I just added the parentheses to make sure that it is being evaluated in the way you want it to be. Might be ok, but I like to sprinkle them around.
Jack of all trades, master of none, though often times better than master of one.
|
|
|
|
|
I would not ask for, and validate, a “log file folder name” (which should be displayed on the Settings form) until I did the “Save” for the settings. At that time, ask for a folder name if the corresponding checkbox is checked and the folder name is missing or invalid.
You could have a “Browse…” button (to get to the file dialog) that is enabled / disabled based on the “logging” checkbox.
(This is the usual “pattern” for an optional file / folder name … IMO).
|
|
|
|
|
I'm doing a project on securing biometrics. Where can I get a biometric application (that includes sample templates and also enrolments can be done)? I will then integrate the app in my C# project where I will be able to encrypt the templates.
|
|
|
|
|
|
Hi!
I wonder if this code is a correct way of using the IDisposable using keyword. Can I put the try-catch block inside it like this, and is it fine to insert a return inside the usage block? (the code is part of a method)
using(StreamReader reader = File.OpenText(fileName))
{
int lineIndex=0;
string line;
while((line=reader.ReadLine()) != null)
{
string[] fields = line.Split(';');
try
{
prodLst.Add(new Produkt(Int64.Parse(fields[0]), (ProdKategoriEnum)Int32.Parse(fields[1]), fields[2], Int32.Parse(fields[3]), Int32.Parse(fields[4])));
prodFileIndexDic.Add(Int64.Parse(fields[0]), lineIndex);
lineIndex++;
}
catch(FormatException e)
{
return false;
}
}
return true;
}
|
|
|
|
|
Entering a try..catch block is not free, in terms of overload. You may enclose your whole while loop in the try..catch block instead (you'll pay the overload only once).
And there's nothing wrong in returning a value inside the block; your StreamReader will be disposed anyway.
If you think it can be a problem, though, you just have to declare a boolean value before using statement, use it in place of your return statements in the using block, and return it at the end.
There are two kinds of people in the world: those who can extrapolate from incomplete data.
|
|
|
|
|
Yes, that's fine - just like a try...catch...finally block will always execute the code in the finally section, it doesn't matter how you exit the using block, the Dispose will still be called.
Personally, I'd probably put the try...catch around the whole loop just to look tidier, and put the return true outside the using so it's more obvious, but it doesn't make any real difference in practice.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Not as an answer to your question, phil.o and OriginalGriff already covered that - but since you're apparently interested to learn about good practice:
When simply returning false in case of an exception, you'll never know why exactly your code failed. You should either log the exception message (and possibly its stacktrace) to a logfile or reconsider if it's not even better to just let your exception "bubble up" - meaning, your method would simply be a void method: Continuation of program execution means all went well, otherwise the exception will also abort the execution of the calling code scope. This is in most cases the best approach and saves you from checking boolean success-return values "everywhere". Only catch an exception if you're going to do something with it: Logging and rethrowing it (potentially wrapped as an InnerException into a custom exception) or actually doing something to remedy the error so that the program can continue normally.
Recursion: see Recursion.
|
|
|
|