Developer-Documentation
Introduction Architecture Execution Logger Gradle Groovy Localization MaryTTS Vocon
Execution Logger Implementation
With the Execution Logger it is possible to log the execution of a graph to a XML file. This is realized with the class ExecutionLogger
. Logging can be switched on and off in the Run Configurations (default is off). This setting is saved in the Preferences
class as well as the path where the log is saved. The default path is /.dialogOS/logs/ in the user home directory.
How the log works
The ExecutionLogger
is being created in SingleDocument.execute()
and then gets passed as a parameter to Graph.execute()
and through the execute()
methods implemented in the different nodes. The saveDocAsXML()
method gets called in SingleDocument.execute()
in the finally block, so the XML file will definitely be saved after the graph ran succesfully or an exception occured while executing.
The XML document is build using jdom 2, a tool to build and output XML files in Java. The XML tag names are saved as class constants to minimize chances of spelling mistakes.
What gets logged
Variables
Initial Variables
The method logInitialVariables()
logs variables to the global_variables
element in the setup element of the document. So this method is just called on start of execution in Graph.execute()
.
Updated Variables
If any global variable is being changed, this gets logged. This is being realized by calling the method logUpdatedVariable()
in a ChangeListener that gets added to every variable.
Nodes
If the execute method in a node gets called (the graph flow reaches the node), the first line of execute()
should be:
logNode(logger);
This calls the method logNode()
in Node which calls logNode()
in the ExecutionLogger.
Subgraph Node
If a node is a GraphNode, not logNode()
but logGraphNode()
gets called. The global variables declared in the Subgraph get added to the GraphNode element as well as all the nodes in a GraphNode.
Exceptions
If an exception occurs while executing the graph, a NodeExecutionException
gets thrown. The ExecutionLogger
should be passed to the exception, so it will be logged. The method logException()
in the ExceptionLogger
gets called by the constructor of the NodeExecutionException
.
Validation
At the moment the validation is disabled because of conflicts between Jing and the MaryTTS plugin. (Presumably MaryTTS tries to use Jing as a XML validator which results in a crash while starting DialogOS.)
Error at xsl:strip-space on line 36 of :
XTSE0280: Element name *|text() is not a valid QName
marytts.exceptions.MaryConfigurationException: Cannot start MARY server
Similar issue: https://github.com/marytts/marytts/issues/455
If the conflict is removed, the validation can be enabled again by setting _validationEnabled
in ExecutionLogger
to true and uncommenting the import of Jing in the build.gradle
of Diamant.
To guarantee that the outputs are consistent the XML document gets validated against a XML schema before saving. The schema is written in RELAX NG Compact. The document is validated using Jing, a tool that can use RELAX NG Compact Schemas to validate XML files in Java. If a document does not pass this validation it does not get saved.
XML Schema (in RELAX NG Compact)
start = Log
Log = element log { Setup, Execution }
Setup = element setup { Project, Start, Global_variables }
Project =
element project {
attribute name { text }
}
Start =
element start {
attribute date { text },
attribute time { text }
}
Global_variables = element global_variables { Var* }
Var =
element var {
Var_attr
}
Var_attr =
attribute name { text },
attribute value { text },
attribute type { text },
attribute is_groovy_only { text }
Execution =
element execution {
Graph
}
Graph = ( Node | Variable_updated | Error )*
Node =
element node {
attribute name { text },
attribute type { text },
attribute transition_time_ms { xsd:nonNegativeInteger },
Global_variables?,
Graph?
}
Variable_updated =
element variable_updated {
Var_attr
}
Error =
element error {
attribute name { text },
attribute source { text },
attribute message { text },
attribute transition_time_ms { xsd:nonNegativeInteger }
}