Skip to content
This repository was archived by the owner on Oct 12, 2018. It is now read-only.

Commit 5ce2d7c

Browse files
committed
Added logging and try/catch for ML and Zorba, along with options to output (save or view) the resulting log.
1 parent a2cd873 commit 5ce2d7c

File tree

1 file changed

+118
-10
lines changed

1 file changed

+118
-10
lines changed

xbin/ml.xqy

+118-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
xquery version "1.0";
1+
xquery version "1.0-ml";
22

33
(:
44
: Module Name: MARC/XML BIB 2 BIBFRAME RDF using MarkLogic
@@ -49,6 +49,9 @@ declare namespace relators = "http://id.loc.gov/vocabulary/relators/";
4949
declare namespace identifiers = "http://id.loc.gov/vocabulary/identifiers/";
5050
declare namespace notes = "http://id.loc.gov/vocabulary/notes/";
5151

52+
declare namespace log = "info:lc/marc2bibframe/logging#";
53+
declare namespace mlerror = "http://marklogic.com/xdmp/error";
54+
5255
declare option xdmp:output "indent-untyped=yes" ;
5356

5457
(:~
@@ -64,10 +67,24 @@ declare variable $baseuri as xs:string := xdmp:get-request-field("baseuri","http
6467
declare variable $marcxmluri as xs:string := xdmp:get-request-field("marcxmluri","");
6568

6669
(:~
67-
: This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON
70+
: This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON, log
6871
:)
6972
declare variable $serialization as xs:string := xdmp:get-request-field("serialization","rdfxml");
7073

74+
(:~
75+
: If set to "true" will write log file to directory.
76+
:)
77+
declare variable $writelog as xs:string := xdmp:get-request-field("writelog","false");
78+
79+
(:~
80+
: Directory for log files. MUST end with a slash.
81+
:)
82+
declare variable $logdir as xs:string := xdmp:get-request-field("logdir","");
83+
84+
let $startDT := fn:current-dateTime()
85+
let $logfilename := fn:replace(fn:substring-before(xs:string($startDT), "."), "-|:", "")
86+
let $logfilename := fn:concat($logdir, $logfilename, '.log.xml')
87+
7188
let $marcxml :=
7289
xdmp:document-get(
7390
$marcxmluri,
@@ -78,33 +95,124 @@ let $marcxml :=
7895

7996
let $marcxml := $marcxml//marcxml:record
8097

81-
let $resources :=
98+
let $result :=
8299
for $r in $marcxml
83100
let $controlnum := xs:string($r/marcxml:controlfield[@tag eq "001"][1])
84101
let $httpuri := fn:concat($baseuri , $controlnum)
85-
let $bibframe := marcbib2bibframe:marcbib2bibframe($r,$httpuri)
86-
return $bibframe/child::node()[fn:name()]
87-
102+
let $r :=
103+
try {
104+
let $rdf := marcbib2bibframe:marcbib2bibframe($r,$httpuri)
105+
let $o := $rdf/child::node()[fn:name()]
106+
let $logmsg :=
107+
element log:success {
108+
attribute uri {$httpuri},
109+
attribute datetime { fn:current-dateTime() }
110+
}
111+
return
112+
element result {
113+
element logmsg {$logmsg},
114+
element rdf {$o}
115+
}
116+
} catch ($e) {
117+
(: ML provides the full stack, but for brevity only take the spawning error. :)
118+
let $stack1 := $e/mlerror:stack/mlerror:frame[1]
119+
let $vars :=
120+
for $v in $stack1/mlerror:variables/mlerror:variable
121+
return
122+
element log:error-variable {
123+
element log:error-name { xs:string($v/mlerror:name) },
124+
element log:error-value { xs:string($v/mlerror:value) }
125+
}
126+
let $logmsg :=
127+
element log:error {
128+
attribute uri {$httpuri},
129+
attribute datetime { fn:current-dateTime() },
130+
element log:error-details {
131+
(: ML appears to be the actual err:* code in mlerror:name :)
132+
element log:error-enginecode { xs:string($e/mlerror:code) },
133+
element log:error-xcode { xs:string($e/mlerror:name) },
134+
element log:error-msg { xs:string($e/mlerror:message) },
135+
element log:error-description { xs:string($e/mlerror:format-string) },
136+
element log:error-expression { xs:string($e/mlerror:expr) },
137+
element log:error-file { xs:string($stack1/mlerror:uri) },
138+
element log:error-line { xs:string($stack1/mlerror:line) },
139+
element log:error-column { xs:string($stack1/mlerror:column) },
140+
element log:error-operation { xs:string($stack1/mlerror:operation) }
141+
},
142+
element log:offending-record {
143+
$r
144+
}
145+
}
146+
return
147+
element result {
148+
element logmsg {$logmsg}
149+
}
150+
}
151+
return
152+
$r
153+
88154
let $rdfxml-raw :=
89155
element rdf:RDF {
90-
$resources
156+
$result//rdf/child::node()[fn:name()]
91157
}
92158

93159
let $rdfxml :=
94160
if ( $serialization ne "rdfxml-raw" ) then
95161
RDFXMLnested2flat:RDFXMLnested2flat($rdfxml-raw, $baseuri)
96162
else
97163
$rdfxml-raw
98-
164+
165+
let $endDT := fn:current-dateTime()
166+
let $log :=
167+
element log:log {
168+
attribute engine {"MarkLogic"},
169+
attribute start {$startDT},
170+
attribute end {$endDT},
171+
attribute source {$marcxmluri},
172+
attribute total-submitted { fn:count($marcxml) },
173+
attribute total-success { fn:count($marcxml) - fn:count($result//logmsg/log:error) },
174+
attribute total-error { fn:count($result//logmsg/log:error) },
175+
$result//logmsg/log:*
176+
}
177+
178+
(: This might be a problem if run in a modules database. :)
179+
let $logwritten :=
180+
if ($writelog eq "true") then
181+
xdmp:save($logfilename, $log,
182+
<options xmlns="xdmp:save">
183+
<indent>yes</indent>
184+
<method>xml</method>
185+
<output-encoding>utf-8</output-encoding>
186+
</options>
187+
)
188+
else
189+
()
190+
191+
(:
192+
For now, not injecting notice about an error into the JSON outputs.
193+
There are a couple of ways to do it (one is a hack, the other is the right way)
194+
but 1) will it break anything and 2) is there a need?
195+
:)
99196
let $response :=
100197
if ($serialization eq "ntriples") then
101-
rdfxml2nt:rdfxml2ntriples($rdfxml)
198+
if (fn:count($result//logmsg/log:error) > 0) then
199+
fn:concat("# Errors encountered. View 'log' for details.", fn:codepoints-to-string(10), rdfxml2nt:rdfxml2ntriples($rdfxml))
200+
else
201+
rdfxml2nt:rdfxml2ntriples($rdfxml)
102202
else if ($serialization eq "json") then
103203
rdfxml2json:rdfxml2json($rdfxml)
104204
else if ($serialization eq "exhibitJSON") then
105205
bfRDFXML2exhibitJSON:bfRDFXML2exhibitJSON($rdfxml, $baseuri)
206+
else if ($serialization eq "log") then
207+
$log
106208
else
107-
$rdfxml
209+
if (fn:count($result//logmsg/log:error) > 0) then
210+
element rdf:RDF {
211+
comment {"Errors encountered. View 'log' for details."},
212+
$rdfxml/*
213+
}
214+
else
215+
$rdfxml
108216

109217
return $response
110218

0 commit comments

Comments
 (0)