log4j writing to a windows share - windows

I have a java application running on windows machines.
Long story short, we have a convention for where we place log files per machine:
\\%COMPUTERNAME%\Logs\<AppNameHere>
So I configured my Java app to startup with -Dmachine.name="%COMPUTERNAME%", and then in my log4j.properties file I specify
log4j.appender.R.File = \\${machine.name}\Logs\MyVerySpecialApplicationName\log.log
But I'm not seeing that directory / file show up when I run my application (the first thing the app does is log a startup message).
So my guess is that log4j / java can't process that windows specific UNC path.
Anyone else run into this issue and figure out a way around it?

I looked at Log4j's source code. It appears to use java.io.File to hold a reference to the filename you specify.
Also, the Javadocs for java.io.File state that UNC paths are supported for the constructor of File (which Log4J uses).
So, on the surface, there's no reason why your configuration won't work; but — and that's the important point to note — Java has a long history of problems with file I/O over SMB (which is pretty much what you're trying to do).
My advice:
Start your application by specifying -Dlog4j.debug=true. The system property will make Log4J spit lots of debug information to help you track the problem.
Attempt using the same configuration, except that, instead of referring to the file with a UNC prefix, simply map the drives (I understand that you're running on Windows). If things work with mapped drives, it means that something in using the UNC prefix is the source of the problem (although I'd doubt it).

You need to put two backlash for each one like in this configuration below
log4j.appender.Log_Arquivo.File=\\\\172.31.88.168\\server10\\soma_10\\logs\\soma_10.log
I hope this help you.

Related

Ship Golang binary with dynamic(config.toml) configuration file

I have a simple go server that works, and gets most of its configuration settings from a toml file.
The current process involves restarting the go build source every time the settings are changed.
What is the correct/most preferred/tested and working way to ship only binary and the config.toml file?
I am still a newbie when it comes to compiling, and i have been reading a lot of texts and still not having a clear understanding on this issue.
Any useful comments will be appreciated.
Config files aren't meant to be embedded in executables. It'd be better to have them reside alongside executables. Since I couldn't get your point on rebuilding complete app just for reloading configuration, I made up my former sentences presuming you're hardcoding.
If we get to the “reloading” topic, I would surely restart my program or send a signal to re-load the configuration. You don't have to do this, because there is a nice library doing this: https://github.com/spf13/viper. It is easy to use and supports live watching for changes on config file. Besides supporting JSON, YAML, TOML and HCL, it can read from environment variables, remote config systems (like Consul and etcd). It's trusted and used by big projects, such as Kubernetes.

Standard location of system-wide configuration files of an app?

Since Windows Vista, our friends from Redmond are putting an end to the habit of storing configuration files in C:\Program Files\<AppName>\config.ini. Ok, they introduced Registry Virtualisation, but it's always better to fix your stuff, right?
I'm planning to fix a pre-Vista app which runs as a service, and which needs to maintain a machine-wide configuration file.
Where do I store the config file? And what would be the most portable/future-proof way of obtaining the path to that location?
You could store the values in the registry in something inheriting from \HKLM\ directly, which would give portability.
If there are a large number of values, or a complex structure to them, then you could store a file location in the registry, and store your configuration at that destination.
After improving my Google-fu starting from a related question, I think I've found the definitive answer in this microsoft blog post which actually describes much more than what I originally wanted to know.

Q: Neo4j-wrapper.conf. Can I put more information into the Wrapper configuration files?

I'm working on updating the Neo4j windows installation process into Powershell and I was thinking that perhaps it could read/write neo4j windows service information from the neo4j-wrapper.conf configuration file.
The Windows wrapper conf has very little information that is related the windows service itself (in fact I think it has no information that is used in the creation, management and removal process!)
My intention is to have the relevant windows service information in the configuration file and then when calls such as Install or Stop are made, then the Service Name can be retrieved from there instead of via command line arguments.
My questions are;
If I put more information into that configuration file, will it affect the linux wrapper?
Is there any reason why I shouldn't put more settings into the configuration file (but only related to a Windows Service)?
Note - My changes would also support this PR;
https://github.com/neo4j/neo4j/pull/4433
Thanks,
Glenn.
I think the answer is, in principle, yes. Putting extra stuff in that file wouldn't hurt anything.
But it's not ideal to have a single file that's used for different purposes on different platforms (I see the presence there of Linux-specific service stuff as a problem rather than something to copied).
The real solution, I think, is for each package build to provide its own copy of that file (or one derived from a common starting point).

file path portability

I have a program that I need to run under *nix and windows. because the program takes file paths from files the issue is what to do about the \ vs / issue.
My current thought is to put in a regex that converts the wrong one to the right one depending on what system I'm on. This will have the effect of letting either type work on either system. Aside from the fact that now I have two problems, does anyone see any other problems?
(Other better solutions are more than welcome)
Edit: the primary issue is getting windows paths to work on unix rather than the other way around.
The / is fully supported in win32 too.
Also see this related question
Windows will generally accept either \ or /,so standardizing on / may make your problem simpler as long as you have complete control over the filenames.
Have you considered creating a "file manager" class that will handle all of the file pathing issues for you? That way in your mail application, when you're loading a data file, you can call something like this.
LoadApplicationData(FileManager.GetDataFilePath)
Then your file manager will detect the environment that it is in and return the proper file path option. That way you can also accomodate for Win32 vs. Unix locatio standards (like Program Files vs /usr or whatever) as well.
Note that Win32 paths are complex when you consider drive letters (no analog on Unix) and the special 'forks' (MacOS pre-X term - likewise no analog on Unix in general, though MacOS X has them - surprise, surprise) that can be provided. Be careful.
Create a parser for your input to create a tree structure of nodes representing directories. Then you can 'save' by walking the tree and writing whatever delimiters you want or optionally doing different things, like checking if the directory exists or writing meta files. This is actually something that I am just now thinking would be useful for my own application :-)
You didn't say what language you are using, so I'm going to selfishly assume c/c++. boost, if you are willing to use it, has a filesystem library. Of course, if you are using a dynamic language, FS abstraction libraries probably already exist there too (e.g. in perl, File::Spec is quite standard).
You haven't told us what sort of files you are reading paths in from. I am going to assume that they are config files. In which case, there are many ways, IMHO the correct answer is to design your program to avoid manipulating paths, if possible. I posted an answer here: https://stackoverflow.com/a/40980510/2345997 which is relevant.
ways:
Add a command line option which allows a user to specify the path in question instead of reading it from a config file.
Add a command line option so that the user can specify a base path. Paths in the config file will be interpreted as located under this base path.
Split your config file into three. One file will have cross platform configuration, another file will have windows only configuration and a final file will have Linux only configuration. Then the user can specify the correct path for both Windows and Linux. On windows your program will read the cross-platform config file and the windows only config file. On Linux it will read the cross-platform file and the Linux only config file.
Add preprocessing to your config file parsing. This will allow you to have one config file where the user can make your program ignore some of the lines in the file depending on which OS the program is running on. Therefore, the user will be able to specify the path to the file twice. Once for Linux, and once for Windows.
Change the design so that the files are always located in the same directory as your executable - then the user only specifies file names in the config file rather than paths to files.
Use a simple function that switches "/" to "\". Then document to the user that they must specify paths as Linux paths and this transformation will be applied for windows.
Create your own path mini-language for this and document it to the user. E.g: "/" - specifies a directory separator, {root} - expands to the root of the filesystem, {cwd} - expands to the current directory, {app} - expands to the path to your application etc... Then the user can specify file paths like: {root}/myfiles/bob.txt on both platforms.
Some paths will work on both platforms. E.g: relative paths like ../my files/bill.txt. Restrict your application to only work with these paths. Document this limitation and how your application handles paths to the user.

Renaming A Running Process' File Image On Windows

I have a Windows service application on Vista SP1 and I've found that users are renaming its executable file (while it's running) and then rebooting, thus causing it to fail to start on next bootup because the service manager can no longer find the exe file since it's been renamed.
I seem to recall that with older versions of Windows you couldn't do this because the OS placed a lock on the file. Even with Vista SP1 I still cannot copy over the existing file when it's running - Windows reports that the file is in use - makes sense. So why should I be allowed to rename it? What happens if Windows needs to page in a new code page from the exe but the file has been renamed since it was started? I ran Process Monitor while renaming the exe file, etc, but Process Mon didn't report anything strange and just logged changing the filename like any other file.
Does anyone know what's going on here behind the scenes? It's seem counter intuitive that Windows would allow a running process' filename (or its dependent DLLs) to be changed. What am I missing here?
your concept is wrong ... the filename is not the center of the file-io universe ... the handle to the open file is. the file is not moved to a different section of disk when you rename it, it's still in the same place and the part of the disk the internal data structure for the open file is still pointing to the same place. bottom line is that your observations are correct. you can rename a running program without causing problems. you can create a new file with the same name as the running program once you've renamed it. this is actually useful behavior if you want to update software while the software is running.
As long as the file is still there, Windows can still read from it - it's the underlying file that matters, not its name.
I can happily rename running executables on my XP machine.
The OS keeps an open handle to the .exe file,. Renaming the file simply changes some filesystem metadata about the file, without invalidating open handles. So when the OS goes to page in more code, it just uses the file handle it already has open.
Replacing the file (writing over its contents) is another matter entirely, and I'm guessing the OS opens with the FILE_SHARE_WRITE flag unset, so no other processes can write to the .exe file.
Might be a stupid question but, why do users have access to rename the file if they are not suppose to rename the file? But yeah, it's allowed because, as the good answers point out, the open handle to the file isn't lost until the application exits. And there are some uses for it as well, even though I'm not convinced updating an application by renaming its file is a good practice.
You might consider having your service listen to changes to the directory that your service is installed in. If it detects a rename, then it could rename itself back to what it's supposed to be.
There are two aspects to the notion of file here:
The data on the disk - that's the actual file.
The file-name (could be several or none) which you can give that data - called directory entries.
What you are renaming is the directory entry, which still references the same data. Windows doesn't care about your doing so, as it still can access the data when it needs to. The running process is mapped to the data, not the name.

Resources