Hi all, here is a take on a LVOOP error, incident, report logger framework (created by Per Hedlund at DVel Sweden, all kudos to him :).
This example also exist as a continuously evolving example in the LabQT LGPL Open Source library.
Class Hierarchy:
Block diagram:
Front Panel:
CSS Tabbed log viewer in a browser:
Have fun and report any bugs here.
Br,
/Roger
Edit 1: Fixed some source distribution issues with missing polymorphic VI's and class methods.
Edit 2: Added a Powerpoint presentation.
Edit 3: Updated in the description and credits.
Edit 4: Fixed a bug in the XML syntax (Thanks Bob )
Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.
First of all: this framework is one of the finest pieces of LabVIEW software craftsmanship I ever got my hands on as well as an excellent starting point for those who are looking for a start into LabVIEW OO programming. Thanks for sharing Roger!
Anyways I ran into trouble when trying to deploy the code bundled into an .exe. While to me it looked like as if with LV13SP1 the Recursive File List.vi can't handle paths below the .exe at runtime (e.g. C:\myLV13.exe\OOLogger) and the following VI gets an empty list and creates error #7 which causes subsequent VIs to fail. Before I describe my workaround, could anybody point me to an article or give me a hint what the simplest way to bundle the framework with an .exe would be.
Thanks in advance
Markus
Hi Markus,
I have added a LV2013 project where I included a build spec that "works for me".
Remember not to use too long path's (to where your .exe is stored for your builds).
LV have some limit to the number of characters a path can contain.
See if you can get it to work?
Br,
/Roger
Glad you got it working.
It's very common with these types of file inclusions in the build specs, so I would not consider it a "workaround".
However, there is another change as well, check out the project main VI as I have a conditional disable structure depending on if the code is running in the dev environment or in the runtime as with the .exe.
Br,
/Roger
Hello,
this is a great framework. Thank you!
I can't find anything about the license.
Which license is used? May I use this framework within commercial applications?
Regards
Matze
Hi Matze,
LGPL is the license used. You can integrate the code into your projects with few caveats.
http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
"The non-(L)GPLed program of yours can then be distributed under any terms if it is not a derivative work".
I am assuming you are not selling the logger framework or derivative work or as a stand alone product? If so, then you might want to consider contacting Per for a licensing fee?
However I think you want to integrate the logging functionality into some measurement/control/simulation application, if that is the case, I see no problems at all!
Roger
Hello Roger,
thank you!
Yes, I want to integrate the framework within a measurement application.
Regards
Matze
Thank you for your contributions -- I have a lot to learn, and you seem to be a thoughtful teacher.
Being an academic type, I want to point out one tiny "oops" -- on your Logging Proposal slide, you show "xml formatted text", but the slash on the end-tags is at the wrong end (</childNode and </xmlRootTag>).
I was also intrigued by noticing that Logger "is a singleton class" -- I recall when reading the LVOOP Design Pattern forum that the Singleton seemed to "get no respect". This code of yours clearly deserves careful study!
Bob Schor (LVOOP beginner)
Hi Bob, thanks for noticing the bug. I'll update the example!
As with all patterns, they should be selected using careful consideration. There is no absolute truth with software development. Most of the choices boils down as to select the least bad in a slew of much worse.
I always try to code my labview programs as close to what I perceive is the spirit and strength of labview - that is selecting pattern(s) which are easy to debug with the "probe" and "highlight" and gives a predictable performance not dependent on too much "asynchronous" code (example, Actor) rattling about in the computation space and time.
Though, in general, try not to overuse the Singleton pattern, or any other patterns (of the day) for that sake.
/Roger
Hi Roger,
I have read the source code for a while, and my goal is to integrate it to my future project as a standard of logging.
There are lots questions arisen as I refactor the source code, and I list in the followings.
Many of the questions are about the design decisions of the ExectionBase.lvclass class.
1.
From my understanding, the purpose of ExecutionBase class as the common ancestor of all other classes is to create reference objects of all other classes through the single element queue (SEQ) and mutex (lock) the use of a reference object through the ExectionBase.Lock and Exection.Unlock methods. In the block diagam of ExectionBase.Lock method, I think the "object output" of "Preserve Run-Time Class.vi" should be wired to the "exectionBase out" output directly. In this way, there is only one reliable instance of an object , storing in the SEQ, and we can enforce a rule "Locking an object as you want to utilize the object and unlocking it after complection.".
2.
In the block diagam of ExectionBase.Lock method, it will check the "isReference" attribute before dequeuing an object. But the value of "isReference" is passed by wire (by value). There will be a problem when other thread has updates this attribute. My suggestion is that wrapping "isRefernce" inside a data value reference (DVR) and the data type of new attribute will be DVR of Boolean. In this way, the new attribute will be thread-safe.
3.
There is an attribute named "children". From the source code, I infer that it is for recording the direct composed objects of a descendant of ExectionBase.lvclass , and I think the name "components" is much proper. But, the composite object (the descendant) keeps its composed objects inside its private data field as an attribute. Why the ExectionBased class need an attribute to record the same information? May you explain the design decision? or I misunderstand the meaning of it.
4.
The definition of "hasOwner" attribute is ambiguous. For example, a singleton may be owned by many other objects as a composed object. Should it be unset as one owner is destroyed?
5.
May you explain the meaning and purpose of "endExection" attribute?
6.
May you explain the meaning and purpose of "eventQueue" attribute?
Thanks for your help
Godel