Is there a way (built-in or underlying java library installed with ColdFusion) that would enable a ColdFusion 10 application to write messages to the Windows Event Log?
You can use Log4J to accomplish this. There is also a DLL that's required to be placed on the PATH of the Windows file system (depending on your environment). See the NTEventLogAppender class for details:
Log4J will be packaged with your build since Hibernate uses it. However, you will likely need to do some extra configuring per the DLL I mentioned above (also noted in the referenced javadocs).
You can also check out Log4jna, which has native appenders unlike Log4J. Using this library will not require you to mess with the DLL dependency for Log4J. This does not come with CF10 though. It's out of scope of your question, but still may be an option to consider.
An example of code you can potentially use if you stick with Log4J (reference to the PatternLayout):
oLogger = createObject("java", "org.apache.log4j.Logger");
oNTAppender = createObject("java", "org.apache.log4j.nt.NTEventLogAppender");
oLayout = createObject("java", "PatternLayout").init("[%c][%l][%p][%thread]: %m%n");
// create the appender with your source and layout
oNTAppender = oNTAppender.init("[your source text]", oLayout);
// add this appender to the logger
oLogger.addAppender(oNTAppender);
Related
The MSI installation would call my (native/C++) custom action functions. Since the DLL is freshly loaded, and the MSIEXEC.EXE process is launched separately for each function (the callable actions, as specified in MSI/WiX script), I cannot use any global data in C/C++ program.
How (or Where) can I store some information about the installation going on?
I cannot use named objects (like shared-memory) as the "process" that launches the DLL to call the "action" function would exit, and OS will not keep the named-object.
I may use an external file to store, but then how would I know (in the DLL's function):
When to delete the external file.
When to find that this function call is the first call (Action/function call Before="LaunchConditions" may help, not very sure).
If I cannot delete the file, I cannot know if "information" is current or stale (i.e. belonging to earlier failed/succeeded MSI run).
"Temporary MSI tables" I have heard of, but not sure how to utilize it.
Preserve Settings: I am a little confused what your custom actions do, to be honest. However, it sounds like they preserve settings from an older application and setup version and put them back in place if the MSI fails to install properly?
Migration Suggestion (please seriously consider this option): Could you install your new MSI package and delete all shortcuts and access to the old application whilst leaving it
installed instead? Your new application version installs to a new path
and a new registry hive, and then you migrate all settings on first
launch of the new application and then kick off the uninstall of the
old application - somehow - or just leave it installed if that is
acceptable? Are there COM servers in your old install? Other things that have global registration?
Custom Action Abstinence: The above is just a suggestion to avoid custom actions. There are many reasons to avoid custom actions (propaganda piece against custom actions). If you migrate settings on application launch you avoid all sequencing, conditioning, impersonation issues along with the technical issues you have already faced (there are many more) associated with custom action use. And crucially you are in a familiar debugging context (application launch code) as opposed to the unfamiliar world of setups and their poor debugability.
Preserving Settings & Data: With regards to saving data and settings in a running MSI instance, the built in mechanism is basically to set properties using Session.Property (COM / VBScript) or MsiSetProperty (Win32) calls. This allows you to preserve strings inside the MSI's Session object. Sort of global data.
Note that properties can only be set in immediate mode (custom actions that don't change the system), and sending the data to deferred mode custom actions (that can make system changes) is quite involved centering around the CustomActionData concept (more on deferred mode & CustomActionData).
Essentially you send a string to the deferred mode custom action by means of a SetProperty custom action in immediate mode. Typically a "home grown" delimited string that you construct in immediate mode and chew up into information pieces when receiving it in deferred mode. You could try to use JSON-strings and similar to make transfer easier and more reliable by serializing and de-serializing objects via JSON strings.
Alternatives?: This set property approach is involved. Some people write to and from the registry during installation, or to a temp file (in the temp folder) and then they clean up during the commit phase of MSI, but I don't like this approach for several reasons. For one thing commit custom actions might not run based on policies on target systems (when rollback is disabled, no commit script is created - see "Commit Execution" section), and it isn't best practice. Adding temporary rows is an interesting option that I have never spent much time on. I doubt you would be able to easily use this to achieve what you need, although I don't really know what you need in detail. I haven't used it properly. Quick sample. This RemoveFile example from WiX might be better.
I am trying to migrate a legacy app that is using camel/cxf (offers some web services that include transformations) to Websphere Liberty 16.0.0.03 (IBM JRE 1.8). Tests are failing because the app uses extensions functions. I tried to disable secure processing as described here.
This change has no effect. That's why I try to switch to Saxon Implementation globally by setting System Property "javax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl" in jvm.options config file. Again - this does not work.
While debugging I can see, that com.ibm.ws.webcontainer.osgi.mbeans.PluginGenerator$2 is overriding the Property with com.ibm.xtq.xslt.jaxp.compiler.TransformerFactoryImpl during Server start. I can see a method "PluginGenerator.revertTransformerFactoryIfNeccessary" in the stack that seems to trigger the change. Afterwards all FactoryFinder.find() will return the non-Saxon implementation.
Can anyone suggest how to either disable secure-processing successfully
or
a way to successfully set a custom TransformerFactory?
BTW: It seems to me like these 2 are bugs - do I report these as regular PMR?
EDIT: possible workaround
As result of the helpful suggestions I added an '#WebListener' that will sets the System Property within the constructor (setting it in contextInitialized is too late as stylesheets seem to be compiled during application start and thus processing fails tests). I bundle this a "patch-jar" with the legacy app.
The Liberty web container plugin generator will only override the xml transformer factory if the IBM JDK is being used.
While the web container performs plugin generation using the IBM JDK, it will swap to an alternate transformer factory, and then reset to the IBM JDK default of which is com.ibm.xtq.xslt.jaxp.compiler.TransformerFactoryImpl.
I think it is worth opening a PMR here. The PluginGenerator should not assume that it started with the default xml transformer factory, and should instead save off the value of javax.xml.transform.TransformerFactory and then restore it after plugin generation has completed.
Temp workaround:
Since the PluginGenerator only swaps the XML transformer factory if you're running on the IBM JDK, you could change to an alternate JDK until your PMR gets resolved.
I agree that this is a bug. The official route for reporting problems is a PMR, but there is enough here for us to understand the problem and fix it through our beta program. If you want to get an iFix on a released version of the product (rather than waiting for it to come out via the beta program) then you will need to raise a PMR.
I was looking at source from the Flask Extension Registry. I probably looked at about 6 or 7 projects and couldn't find any of them logging output.
My question is: is it OK to do so? If so, should I use app.logger or my own logger?
Yes, you should log - no, you should not use the application logger since the user will not the be able to configure your extension's logging verbosity separately from their own.
Instead, create your own logger using Python's built-in logging module. Add a NullHandler (Python 3 has one, create your own NullHandler for Python2) so that by default your library will not log anything. Add a documentation section explaining how the user can access your logger to setup handlers (and explicitly configure levels, should they so desire).
As is often the case, there is some very good advice on this subject in Python's documentation:
Configuring Logging for a Library
When developing a library which uses logging, you should take care to document how the library uses logging - for example, the names of loggers used. Some consideration also needs to be given to its logging configuration. If the using application does not use logging, and library code makes logging calls, then (as described in the previous section) events of severity WARNING and greater will be printed to sys.stderr. This is regarded as the best default behaviour.
If for some reason you don’t want these messages printed in the absence of any logging configuration, you can attach a do-nothing handler to the top-level logger for your library. This avoids the message being printed, since a handler will be always be found for the library’s events: it just doesn’t produce any output. If the library user configures logging for application use, presumably that configuration will add some handlers, and if levels are suitably configured then logging calls made in library code will send output to those handlers, as normal.
We have several Windows 8 Store C++ apps that need to maintain configuration and data files.
Files are written in subfolders of Windows::Storage::ApplicationData::Current->LocalFolder. Example:
C:\Users\<username>\AppData\Local\Packages\<packagename>\LocalState\SubFolder1\SubFolder2\data.txt
In Windows 8.1 we have received a few reports from users that say state isn't remembered between app invocations. Upon closer inspection the files are not created (the subfolders are indeed created, but there are no files inside them)
Notes:
Subfolders are created using CreateDirectory(), files are created using fopen()
Files are created/opened using absolute paths
This always worked under Windows 8.0 and the code has not been changed since. In fact, one of our user reports stated that the app saved files fine under Windows 8.0, but stopped saving after the user upgraded to Windows 8.1.
We have not been able to replicate the issue locally using Windows 8.1. We're not sure how common this failure is, but we estimate that most users are unaffected. Affected users do not appear to have any special hardware/software configuration.
If a user is affected, then files are consistently never saved, even after retrying or uninstalling and re-installing the app (i.e., it's not a case of intermittent failure)
It's hard to get error information given (i) the rarity of the issue (ii) the fact that the logs that would reveal this are by definition not saved, and (iii) the apps don't require internet connectivity so there is no alternative communication channel.
Can anyone think of any reason why this might fail under Windows 8.1?
Are there non-ascii characters in path to appdata? CreateDirectory has unicode version, but fopen takes const char* strings as argument.
If I were you, I'd try to abstract away from OS-specific calls using something like boost or Qt. That should work, because Qt uses unicode string for opening files and Boost should have something similar (unsure about this one).
Also on windows compiler _wfopen may be present. It is the same as fopen, but takes wchar_t strings as argument. It should work for you, but you'll need a few ifdefs here and there.
You could also try setting current directory with function that supports unicode and then calling fopen, but I wouldn't call it a "clean" solution.
Anyway, when you run into problem that is related to system calls, then on machine with a problem you can monitor calls using something like process monitor. You could instruct user with a problem to do that and send you a log.
Why don't you use the Windows.Storage classes to work with filesystem? WinRT is recommended way to work with IO not legacy C API. I believe it is more robust approach and you could get more info about the cause from WinRT exception rather than from an unknown failure of old API.
I have a C++ library, which is used in both Linux and Windows.
I want to enable the user to control the debug level (0 - no debug, 1 - only critical errors ... 5 - informative debug information).
The debug log is printed to a text file.
In Windows, I can do it using a registry value (DWORD DebugLevel).
What can be a good replacement which works also for Linux?
(Without 3rd party tools, for example Linux "registry").
Thanks in advance!
Does your library have some sort of initialisation function? Make the level a parameter to that function. Ideally store the passed-in value in a context structure or class if it makes sense for your API (i.e. if you require clients to always operate via a "context") - but if not, a global might be reasonable.
If it's largely for development purposes (ie the "user" you refer to is a developer using your library, not the end user of that code), the quickest/easiest way is to use an environment variable.
If it's to be controlled by the end-user, you probably need to extend your API so that the app developer can set the debug level in code, after reading his configuration files -- you wouldn't normally have a separate config file for just one library used by a program.
You can use the log4cxx framework. This is configurable through a file. I haven't tried it yet, but it should work with Windows too.
You could use a configuration file in /etc/YOURAPP or ~/.YOURAPP or ~/.config/YOURAPP