Where are the best locations to write an error log in Windows? - permissions

Where would you write an error log file, say ErrorLog.txt, in Windows? Keep in mind the path would need to be open to basic users for file write permissions.
I know the eventlog is a possible location for writing errors, but does it work for "user" level permissions?
EDIT: I am targeting Windows 2003, but I was posing the question in such a way as to have a "General Guideline" for where to write error logs.
As for the EventLog, I have had issues before in an ASP.NET application where I wanted to log to the Windows event log, but I had security issues causing me heartache. (I do not recall the issues I had, but remember having them.)

Have you considered logging the event viewer instead? If you want to write your own log, I suggest the users local app setting directory. Make a product directory under there. It's different on different version of Windows.
On Vista, you cannot put files like this under c:\program files. You will run into a lot of problems with it.
In .NET, you can find out this folder with this:
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
And the Event Log is fairly simple to use too:
http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx

Text files are great for a server application (you did say Windows 2003). You should have a separate log file for each server application, the location is really a matter of convention to agree with administrators. E.g. for ASP.NET apps I've often seen them placed on a separate disk from the application under a folder structure that mimics the virtual directory structure.
For client apps, one disadvantage of text files is that a user may start multiple copies of your application (unless you've taken specific steps to prevent this). So you have the problem of contention if multiple instances attempt to write to the same log file. For this reason I would always prefer the Windows Event Log for client apps. One caveat is that you need to be an administrator to create an event log - this can be done e.g. by the setup package.
If you do use a file, I'd suggest using the folder Environment.SpecialFolder.LocalApplicationData rather than SpecialFolder.ApplicationData as suggested by others. LocalApplicationData is on the local disk: you don't want network problems to stop you from logging when the user has a roaming profile. For a WinForms application, use Application.LocalUserAppDataPath.
In either case, I would use a configuration file to decide where to log, so that you can easily change it. E.g. if you use Log4Net or a similar framework, you can easily configure whether to log to a text file, event log, both or elsewhere (e.g. a database) without changing your app.

The standard location(s) are:
C:\Documents and Settings\All Users\Application Data\MyApp
or
C:\Documents and Settings\%Username%\Application Data\MyApp
(aka %UserProfile%\Application Data\MyApp) which would match your user level permission requirement. It also separates logs created by different users.
Using .NET runtime, these can be built as:
AppDir=
System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
or
AppDir=
System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
followed by:
MyAppDir = IO.Path.Combine(AppDir,'MyApp')
(Which, hopefully, maps Vista profiles too).

Personally, I would suggest using the Windows event log, it's great. If you can't, then write the file to the ApplicationData directory or the ProgramData (Application Data for all users on Windows XP) directory.

The Windows event log is definitely the way to go for logging of errors. You're not limited to the "Application" log as it's possible to create a new log target (e.g. "My Application"). That may need to be done as part of setup as I'm not sure if it requires administrative privileges or not. There's a Microsoft example in C# at http://support.microsoft.com/kb/307024.
Windows 2008 also has Event Log Forwarding which can be quite handy with server applications.

I agree with Lou on this, but I prefer to set this up in a configuration file like Joe said. You can use
file value="${APPDATA}/Test/log-file.txt"
("Test" could be whatever you want, or removed entirely) in the configuration file, which causes the log file to be written to "/Documents and Settings/LoginUser/Application
Data/Test" on Windows XP and to "/Users/LoginUser/AppData/Roaming/Test on Windows Vista.
I am just adding this as I just spent way too much time figuring how to make this work on Windows Vista...
This works as-is with Windows applications. To use logging in web applications, I found Phil Haack's blog entry on this to be a great resource:
http://haacked.com/archive/2005/03/07/ConfiguringLog4NetForWebApplications.aspx

%TEMP% is always a good location for logs I find.

Going against the grain here - it depends on what you need to do. Sometimes you need to manipulate the results, so log.txt is the way to go. It's simple, mutable, and easy to search.
Take an example from Joel. Fogbugz will send a log / dump of error messages via http to their server. You could do the same and not have to worry about the user's access rights on their drive.

I personally don't like to use the Windows Event Log where I am right now because we do not have access to the production servers, so that would mean that we would need to request access every time we wanted to look at the errors. It is not a speedy process unfortunately, so your troubleshooting is completely haulted by waiting for someone else. I also don't like that they kind of get lost within the ones from other applications. Sure you can sort, but it's just a bit of a nucance scrolling down. What you use will end up being a combination of personal preference coupled along with limitations of the enviroment you are working in. (log file, event log, or database)

Put it in the directory of the application. The users will need access to the folder to run and execute the application, and you can check write access on application startup.
The event log is a pain to use for troubleshooting, but you should still post significant errors there.
EDIT - You should look into the MS Application Blocks for logging if you are using .NET. They really make life easy.
Jeez Karma-killers. Next time I won't even offer a suggestion when the poster puts up an incomplete post.

Related

Pdf2htmlEX common error "Cannot load font"

Running the pdf2htmlEX.exe Windows binary from the command prompt works as expected. While, running the pdf2htmlEX Windows binary in a wrapper (.Net in my case) I received an error like the one below.
__tmp_font1.ttf is not in a known format (or uses features of that format fontfo
rge does not support, or is so badly corrupted as to be unreadable)
Cannot load font C:\Users\admin\AppData\Local\Temp\pdf2htmlEX-5RLDCX/__tmp_fo
nt1.ttf
This is a pretty ambiguous error, and appears to be frequent among users when using the windows binary version.
Apparently Lu Wang wasn't able to offer a solution for Windows users, as all posts related are marked 'insufficient info'. Unfortunately, the pdf2htmlEX project is also archived, and no new comments can be added, so I'm adding this information here in the hope that this may help someone else in the future.
In my scenario, the library is called via an ASP.Net wrapper method using System.Diagnostics.Process to convert uploaded files into HTML versions. The Pdf2htmlEX library would work without issue from the Command Prompt, and for some reason, would also work perfectly in my development environment, but not in a production environment (Both of which are Windows Server 2012R2).
My first assumption, and correctly so, was that there was a permissions issue. Pdf2htmlEX uses FontForge internally to handle fonts, and one or both use the Windows Temp directory by default to store resource files used in the creation of the HTML and/or other files. And, I 'believe' although not confirmed, that it also may use the active user's %USERPROFILE%\AppData\Local\Temp folder...
When running test commands from Command Prompt, you are operating under your user context, and everything your user can do, Pdf2htmlEX can do. So everything works as expected.
In a server environment, the process is operating under the ApplicationPoolIdentity, a special IIS user type with limited permissions. Here it failed for me. While, I'd see folders and files created in the Windows Temp folder, they couldn't be opened by Pdf2HtmlEX to create the end files elsewhere.
Solution: (there may be other solutions for your individual case)
In my case, adding a new system user, adding that user to the Users group, and then setting the IIS worker process to that account resolved the issue. The reason I believe, is that the Users group has read/write access to the Windows Temp directory, and potentially other required areas of the system required for Pdf2htmlEX to complete.

ServicePulse gets hit on security scan

We are running a Nessus security scan. Unfortunately Particulars ServicePulse executable is coming up as a hit.
Path : c:\program files (x86)\particular software\servicepulse\servicepulse.host.exe
Used by services : Particular.ServicePulse
File write allowed for groups : Everyone
Full control of directory allowed for groups : Everyone
I thought it might be because of the service so I disable the service but it still comes up as a hit in the scan.
Is this software needed for NServiceBus if we are not using a dashboard to monitor?
It looks like the security scan does not like Everyone having full control. As long as the account the service is running under has Read and execute permissions it will work. By default ServicePulse is installed to run using the Local System account.
There is an issue open to address this https://github.com/Particular/ServicePulse/issues/514
ServicePulse dashboard gives an overview of your endpoints and failing messages.
If you are not using it to begin with, your endpoints will continue running, but you'll be flying blind as ServiceControl will be ingesting any failed messages and you won't see if there are any. If you use Heartbeat plugin or any other custom checks, that info will be not visible either.
There's an option of integrating with ServiceControl events, though I suggest you examine how your environment is set up in regards to ServiceControl, and don't disable ServicePulse without understanding the implications of disabling it and knowing your monitoring is covered.
The scan is complaining about file permissions that are too open. Everyone should not have write permissions in any Program Files folder.
I inspected my installation folder and have the same issue.
The fix is relatively easy:
Select the properties of folder C:\Program Files (x86)\Particular Software\ServicePulse
Select the Security tab
Select Advanced, a new dialog opens
Select Enable inheritance
Select OK and Yes on any confirmation dialog
Select Advanced again
Check Replace all child object permission entries with inheritable permissions entries from this object
Select OK and Yes on any confirmation dialog
Select Advanced again for the 3rd time
Remove the current entries where Inherited from states None, on my system those were Everyone and System, make sure that you see all other entries inherited from the parent folder and make sure you do not remove any of them.
Select OK and Yes on any confirmation dialog
It seems like hard procedure but that is because I'm being very detailed here. Some steps potentially can be combined but doing one change at a time keeps things easy to understand.
Now your file permissions are correctly set and comply to your security audit software.

Modify audit policy (group policy)

I'd like to change object audit policy with vb.net. Like enabling Object Access auditing. Is that possible? If not, is powershell an option? I know I can get gpedit running on any version of Windows, but I want to be able to change the setting programmatically.
Also, I do know some settings can be changed by Registry, but I haven't seen one for audit policy.
http://www.lshift.net/blog/2013/03/25/programmatically-updating-local-policy-in-windows/
I found this, but will give it a try in a little while.
Update: It is possible to import, via VB (or probably any other language), but using REG IMPORT. Make sure you're putting the .REG file where System can access it (System does not have the same privileges as Administrator). You'd have to launch a separate app that runs as System and, on load, imports a registry key. You can run as System using PSTools (psexec), from Sysinternals. You can also do it by creating a service, running the service, then deleting the service: Running application as System (without PSTools)
I realized all the links I thought were the answer, were not. They all change the Audit Policy tab, and I can already do that programmatically. What I want to change is the global audit policy, which is only available in Group Policy (gpedit.msc). Of course, you can "install" it on any version of Windows, but I want a solution that doesn't require the end user to have to set it (aka not use gpedit.msc).
I knew that Process Monitor could monitor virtually anything going on in the background, and one link in my comments also was using Process Monitor (comments of my OP). So, I figured that was really my only way. Naturally, you'd think mmc.exe is the one to look for, but it's not. It does a TON of registry open/query/enum/closes. However, no setting or deleting. I decided to look a little before and after the large block of mmc operations (well and of course anywhere in between). Anything that wasn't mmc but happened in the exact timeframe. I found lsass had done some setting and deleting. It was changing the value of a Registry key that is owned by System. I used PSTools to run regedit as System, so I could access the key. I then used gpedit to switch back and forth (from No Auditing to Success), and found it always set the same values (something like 0 for off and 1 for on). I exported the keys when I changed the values in gpedit, and then imported them to test. I can confirm it works by reopening gpedit after importing, and the value changes. I can also confirm simply by enabling Auditing on a folder, and seeing logs in Event Viewer.
tl;dr
HKEY_LOCAL_MACHINE\SECURITY\Policy\PolAdtEv\(Default) is the you want.
Download the .reg files here
Run this in an elevated command prompt: psexec -i -s regedit
Import the .reg file you need.
Confirm by reopening gpedit.msc and checking Event Viewer (Security)
Don't trust the .reg files? Here are the values you if you'd rather create them yourself. Value type is REG_NONE, so #=hex(0).
No Audit: 00010000090000007e00000001000000030000000300010001000100000001000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000100000000000000000001000000010000000000000000000000000000000000000000000000fe7f05000a000e00030004000600060004000400
Success: 00010000090000007e00000001000000030000000300010001000100000001000000000000000300000001000100010001000100010001000100010001000100010001000100000000000000000000000000000001000100000000000000000001000000010000000000000000000000000000000000000000000000fe7f05000a000e00030004000600060004000400

Requested registry access is not allowed on remote box

We have developed a somewhat diffuse system for handling component installation and upgrades across server environments in an automated manner. It worked happily on our development environment, but I've run into a new problem I've not seen before when attempting to deploy it to a live environment.
The environment in question comprises ten servers, five each on two different geographical sites and domains. Each server runs a WCF based windows service that allows it to talk to each of the other servers and thus keep a track of what's installed where. To facilitate this process we make use of machine level environment variables - and modifying these obviously means registry changes.
Having got all this set up, my first attempts to use the system to install stuff seemed to work, but on one box in particular I'm getting "Requested registry access is not allowed" errors when the code tries to modify the environment variables. I've googled this, obviously, but there seem to be a variety of different causes and I'm really not sure which are the applicable ones. It doesn't help that this is a live environment and that our system has relatively limited internal logging capability.
The only clue I've got is that the guy who did the install on the development boxes wrote a very patch set of documentation on the process. This includes an instruction to modify the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy value in the registry and set it to 1. I skipped this during the installation as it looked like a rather dubious security risk. Reading the documentation about this key, it looks relevant but my initial attempts at installing stuff on other boxes without this setting enabled worked fine. Sadly the author went on extended leave over the holidays yesterday and he left no explanation of why this key was needed, so we're a bit in the dark.
Can anyone help us toward the light?
Cheers,
Matt
I've seen this error when code tries to write to the event log using something like EventLog.WriteEntry() and a source that is not a registered event source is specified. When a source is specified that has not previously been registered, it will attempt to register the source, which involves writing to the registry.
I would suggest taking a look at SysInternals Process Monitor:
http://technet.microsoft.com/en-us/sysinternals/bb896645
You can use this to monitor registry access and find out what key you're getting the access denied error on. This may give you some insight as to what is causing the problem.
Essentially he's disabling part of the Remote User Account Control. Without setting the value, Remote UAC strips administrative privileges from account tokens remotely accessing the machine. Yes, it does have security implications. See Description of User Account Control and remote restrictions in Windows Vista for an explanation.

Issues with DB after publishing via Database Publishing Wizard from MSFT

I work on quite a few DotNetNuke sites, and occasionally (I haven't figured out the common factor yet), when I use the Database Publishing Wizard from Microsoft to create scripts for the site I've created on my Dev server, after running the scripts at the host (usually GoDaddy.com), and uploading the site files, I get an error... I'm 99.9% sure that it's not file related, so not sure where to begin in the DB. Unfortunately with DotNetNuke you don't get the YSOD, but a generic error, with no real way to find the actual exception that has occured.
I'm just curious if anyone has had similar deployment issues using the Database Publishing Wizard, and if so, how they overcame them? I own the RedGate toolset, but some hosts like GoDaddy don't allow you to direct connect to their servers...
The Database Publishing Wizard's generated scripts usually need to be tweaked since it sometimes gets the order wrong of table/procedure creation when dealing with constraints. What I do is first backup the database, then run the script, and if I get an error, I move that query to the end of the script. Continue restoring the database and running the script until it works.
There are two areas that I would look at -
Are you running in the dbo schema and was your scripted database
using dbo?
Are you using an objectqualifier in either your dev or your
production environment? (look at your sqldataprovider configuration
settings)
You should be able to expose the underlying error message by setting the following in the web.config:
customErrors mode="Off"
Could you elaborate on "and uploading the site files"? New instance of DNN? updating an existing site? upgrading DNN version? If upgrade or update -- what files are you adding/overwriting?
Also, when using GoDaddy, can you check to verify that the web site's identity (network service or asp.net machine account depending on your IIS version) has sufficient permissions to the website's file system? It should have modify permissions and these may need to be reapplied if you are overwriting files.
IIS6 (XP, Server 2000, 2003) = ASP.Net Machine Account
IIS7 (Vista, Server 2008) = Network Service
Test your generated scripts on a new local database (using the free SQL Express product or the full meal deal). If it runs fine locally, then you can be confident that it will run elsewhere, all things being equal.
If it bombs when you run it locally, use the process of elimination and work your way through the script execution to find the offending code.
My hunch is that the order of scripts could be off. I think I've had that happen before with the database publishing wizard.
Just read your follow up. In every case that I've had your problem, it was always something to do with the connection string in web.config. Even after hours of staring at it, it was always a connection string issue in web.config. Get up, take a walk and then come back.
If you are getting one of DNN's error pages, there is a chance it may have logged the error to the eventlog table.
Depending on exactly what is happening and what DNN is showing you you might be able to manually look inside the EventLog table, pull out the XML data stored there, and parse it to find the stack trace and detailed information regarding the specific error at hand.
I have found however though that I get MUCH better overall experiences with deployments using backups and restores of my database, that way I am 100% sure that all objects moved correctly, and honestly it works better in my experience.
With GoDaddy I know another MAJOR common issue is incorrect file permissions, preventing DNN from modifying the web.config and other files that it needs to do.