-
Notifications
You must be signed in to change notification settings - Fork 7
Feature eodtime #108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Feature eodtime #108
Changes from all commits
65516d1
3538ed6
79b5400
d5874bd
bb637de
5f09606
eb051c8
32d7faa
bb9f1a2
503a921
a2f91d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| # di.eodtime | ||
|
|
||
| End-of-day time management for kdb+ tickerplant processes. Resolves the current trading date in a configurable roll timezone, calculates the next EOD roll timestamp in UTC, and computes a daily UTC offset used to timestamp incoming data. | ||
|
|
||
| --- | ||
|
|
||
| ## Features | ||
|
|
||
| - Compute the current trading date in a configurable roll timezone, handling DST transitions automatically | ||
| - Calculate the UTC timestamp of the next EOD roll from any given UTC timestamp, with support for non-midnight roll times via `rolltimeoffset` | ||
| - Compute a live UTC offset for a configurable data timezone, refreshable after each roll to capture DST changes | ||
| - Store and expose the current trading date, next roll timestamp, and daily adjustment offset as inspectable module state | ||
| - State setters allow tickerplant and segmented tickerplant processes to advance state after a roll without re-initialising | ||
| - `"GMT"`, `"UTC"`, and `"Etc/GMT"` are handled as zero-offset shortcuts without a timezone lookup - the module works out of the box with TorQ defaults | ||
|
|
||
| --- | ||
|
|
||
| ## Dependencies | ||
|
|
||
| | Dependency | Key | Required | Description | | ||
| |---|---|---|---| | ||
| | logger | `` `log `` | yes | `info` - binary `{[c;m]}` where `c` is a symbol context and `m` is a string. `warn` and `error` are accepted if present but never called by this module | | ||
|
|
||
| **Hard dependency:** `di.tz` - loaded automatically when the module is imported. | ||
|
|
||
| The `log` dependency must be passed to `init` inside the `configs` dict keyed on `` `log ``. The module throws immediately if `log` is absent or `info` is missing. `warn` and `error` are optional, but the dict passed in must already match the binary `{[c;m]}` contract - the module does not detect or adapt other shapes (e.g. a raw `kx.log` instance, which is monadic). If you want to use `kx.log`, load it and write your own `{[c;m]}` wrapper around it before passing it in. | ||
|
|
||
| Configuration keys `rolltimezone`, `datatimezone`, and `rolltimeoffset` are all optional - omit any or all of them and the module falls back to sensible defaults (GMT timezone, midnight roll). See Initialisation for full details. | ||
|
|
||
| --- | ||
|
|
||
| ## Initialisation | ||
|
|
||
| `init[deps]` takes a single dictionary combining the `log` dependency with any configuration overrides. | ||
|
|
||
| | Key | Required | Description | | ||
| |---|---|---| | ||
| | `` `log `` | yes | Log dep - at minimum `info` function `{[c;m]}` | | ||
| | `` `rolltimezone `` | no | Timezone for EOD roll scheduling. Default: `` `$"GMT" `` | | ||
| | `` `datatimezone `` | no | Timezone for stamping incoming data. Default: `` `$"GMT" `` | | ||
| | `` `rolltimeoffset `` | no | Offset from midnight for the EOD roll (e.g. `0D17:00:00.000` for a 5pm roll). Default: `0D` | | ||
|
|
||
| `init` must be called before any other function. It computes the initial values of `d`, `nextroll`, and `dailyadj`. Calling getters before `init` returns uninitialised defaults (`0Nd`, `0Wp`, `0D`) which will produce wrong results in downstream processes. | ||
|
|
||
| Timezone values should be standard identifiers in `"Region/City"` format (e.g. `"Europe/London"`, `"America/New_York"`). `"GMT"`, `"UTC"`, and `"Etc/GMT"` are zero-offset shortcuts handled directly without a `di.tz` lookup. Note: `"Etc/UTC"` is valid and passed through to `di.tz` normally. | ||
|
|
||
| --- | ||
|
|
||
| ## Exported Functions | ||
|
|
||
| ### `init[deps]` | ||
| Initialise the module. Validates the log dependency, applies config, and computes initial values of `d`, `nextroll`, and `dailyadj`. | ||
| ```q | ||
| eodtime.init[`log`rolltimezone`datatimezone`rolltimeoffset!(logdep;`$"Europe/London";`$"GMT";0D)] | ||
| / or with defaults only: | ||
| eodtime.init[enlist[`log]!enlist logdep] | ||
| ``` | ||
|
|
||
| ### `getd[]` | ||
| Return the current trading date in the roll timezone. | ||
| ```q | ||
| eodtime.getd[] | ||
| / 2025.06.01 | ||
| ``` | ||
|
|
||
| ### `getnextroll[]` | ||
| Return the UTC timestamp of the next scheduled EOD roll. | ||
| ```q | ||
| eodtime.getnextroll[] | ||
| / 2025.06.02D00:00:00.000000000 | ||
| ``` | ||
|
|
||
| ### `getdailyadj[]` | ||
| Return the **cached** UTC offset for the data timezone - the value stored at the last `init` or `setdailyadj` call. | ||
| ```q | ||
| eodtime.getdailyadj[] | ||
| / 0D01:00:00.000000000 | ||
| ``` | ||
|
|
||
| ### `getdailyadjustment[]` | ||
| **Recompute** the UTC offset for the data timezone at the current time. Call after an EOD roll to get a fresh offset - important when the data timezone observes DST. | ||
| ```q | ||
| eodtime.getdailyadjustment[] | ||
| / 0D01:00:00.000000000 | ||
| ``` | ||
|
|
||
| ### `getroll[p]` | ||
| Compute the UTC timestamp of the next EOD roll after UTC timestamp `p`. Returns today's roll time if the roll has not yet passed; tomorrow's if it has. | ||
| ```q | ||
| eodtime.getroll[.z.p] | ||
| / 2025.06.02D00:00:00.000000000 | ||
| ``` | ||
|
|
||
| ### `setnextroll[x]` | ||
| Update the stored next roll timestamp. Called by the tickerplant after completing an EOD roll. | ||
| ```q | ||
| eodtime.setnextroll eodtime.getroll[.z.p] | ||
| ``` | ||
|
|
||
| ### `setdailyadj[x]` | ||
| Update the stored daily adjustment offset. Called by the tickerplant after an EOD roll to refresh the offset for the new day. | ||
| ```q | ||
| eodtime.setdailyadj eodtime.getdailyadjustment[] | ||
| ``` | ||
|
|
||
| ### `setd[x]` | ||
| Update the stored trading date. Called by the segmented tickerplant to advance the date after an EOD roll. | ||
| ```q | ||
| eodtime.setd[1+eodtime.getd[]] | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Usage Example | ||
|
|
||
| ```q | ||
| / log dep must already match the binary {[c;m]} contract - write your own, or use di.log: | ||
| / logging:use`di.log | ||
| / eodtime.init[logging.logdict] | ||
| logdep:`info`warn`error!({[c;m]};{[c;m]};{[c;m]}) | ||
|
|
||
| / load and initialise for a London-based system rolling at midnight | ||
| eodtime:use`di.eodtime | ||
| eodtime.init[`log`rolltimezone`datatimezone`rolltimeoffset!(logdep;`$"Europe/London";`$"GMT";0D)] | ||
|
|
||
| / check current state | ||
| eodtime.getd[] / today's trading date in London time | ||
| eodtime.getnextroll[] / next midnight UTC (23:00 UTC in summer) | ||
| eodtime.getdailyadj[] / current UTC offset for data timestamping | ||
|
|
||
| / at EOD roll - tickerplant advances state | ||
| eodtime.setnextroll eodtime.getroll[.z.p]; | ||
| eodtime.setdailyadj eodtime.getdailyadjustment[]; | ||
|
|
||
| / at EOD roll - segmented tickerplant advances date | ||
| eodtime.setd[1+eodtime.getd[]] | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Running Tests | ||
|
|
||
| ```q | ||
| k4unit:use`di.k4unit | ||
| k4unit.moduletest`di.eodtime | ||
| ``` | ||
|
|
||
| The test suite injects a no-op mock logger and a capturing logger that records `(level;msg)` pairs for assertion. It covers: dependency validation (non-dict deps throws; missing `log` key throws; non-dict log value throws; missing `info` key throws; `info`-only log dict succeeds); config defaults and overrides; `getroll` with GMT and non-GMT roll timezones including DST transitions (London winter vs summer, and an overnight DST-transition rollover); `getdailyadjustment` with UTC shortcuts and DST-aware timezones; state setters (`setnextroll`, `setdailyadj`, `setd`) and their corresponding getters; and a six-level log dict (matching `di.log`'s `logdict` shape) accepted as-is by `init`. | ||
|
|
||
| --- | ||
|
|
||
| ## Notes | ||
|
|
||
| - `rolltimeoffset` adjusts the roll time from midnight - e.g. `0D17:00:00.000` produces a 5pm local roll | ||
| - `getdailyadj` returns the cached offset; `getdailyadjustment` recomputes it live. Always call `getdailyadjustment` after an EOD roll rather than relying on the cached value | ||
| - `"GMT"`, `"UTC"`, and `"Etc/GMT"` are zero-offset shortcuts not passed to `di.tz`. `"Etc/UTC"` is valid and passes through normally | ||
| - Only `info` is required in the log dep - `warn` and `error` are accepted if present but never called by this module. The dep must already match the binary `{[c;m]}` contract; the module does not adapt other shapes |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| / end-of-day time management - date resolution, roll scheduling and data timestamp adjustment | ||
|
|
||
| / utc-equivalent timezone names - zero offset from utc so no timezone lookup required | ||
| utczones:`$("GMT";"UTC";"Etc/GMT"); | ||
|
|
||
| / ============================================================ | ||
| / module state and defaults | ||
| / ============================================================ | ||
|
|
||
| / roll timezone for eod scheduling - overwritten by init | ||
| rolltimezone:`$"GMT"; | ||
|
|
||
| / data timezone for incoming data timestamping - overwritten by init | ||
| datatimezone:`$"GMT"; | ||
|
|
||
| / offset from midnight for the eod roll - overwritten by init | ||
| rolltimeoffset:0D00:00:00.000; | ||
|
|
||
| / current trading date in rolltimezone - set by init | ||
| d:0Nd; | ||
|
|
||
| / utc timestamp of next eod roll - set by init | ||
| nextroll:0Wp; | ||
|
|
||
| / utc offset for datatimezone data stamping - set by init | ||
| dailyadj:0D00:00:00.000; | ||
|
|
||
| / ============================================================ | ||
| / internal helpers | ||
| / ============================================================ | ||
|
|
||
| / returns timespan offset from utc for rolltimezone at timestamp p | ||
| adjtime:{[p] | ||
| / utc-equivalent timezones have zero offset | ||
| if[rolltimezone in utczones;:0D]; | ||
| `timespan$tz.gmttolocal[rolltimezone;p]-p | ||
| }; | ||
|
|
||
| / returns the date in rolltimezone for utc timestamp p | ||
| getday:{[p]"d"$(p+adjtime[p])-rolltimeoffset}; | ||
|
|
||
| / ============================================================ | ||
| / public api | ||
| / ============================================================ | ||
|
|
||
| / recomputes utc offset for datatimezone at current time | ||
| / call after an eod roll to get a fresh offset - important when datatimezone observes dst | ||
| getdailyadjustment:{ | ||
| / utc-equivalent timezones have zero offset | ||
| if[datatimezone in utczones;:0D]; | ||
| `timespan$tz.gmttolocal[datatimezone;.z.p]-.z.p | ||
| }; | ||
|
|
||
| / returns normalised roll time-of-day (utc) for the zone offset at timestamp p, wrapped to [0D,1D) | ||
| rolltod:{[p]`timespan$(mod) . "j"$(rolltimeoffset-adjtime[p]),1D}; | ||
|
|
||
| / returns utc timestamp of next eod roll after utc timestamp p | ||
| getroll:{[p] | ||
| z:rolltod[p]; | ||
| / kdb-x 5.0: comparing timespan to timestamp checks against p's time-of-day component - true means roll has already passed | ||
| / recompute the offset at p+1D on rollover - a dst transition overnight can shift it between today and tomorrow | ||
| $[z<=p;("d"$p+1D)+rolltod[p+1D];("d"$p)+z] | ||
| }; | ||
|
|
||
| / state getters | ||
| getd:{d}; | ||
| getnextroll:{nextroll}; | ||
| getdailyadj:{dailyadj}; | ||
|
|
||
| / state setters | ||
| setnextroll:{.z.m.nextroll:x}; | ||
| setdailyadj:{.z.m.dailyadj:x}; | ||
| setd:{.z.m.d:x}; | ||
|
|
||
| init:{[deps] | ||
| / initialise the eodtime module - validate deps, apply config, compute initial state | ||
| / deps: dict containing `log (required) plus optional `rolltimezone, `datatimezone, `rolltimeoffset | ||
| / log dep: at minimum `info!{[c;m]} - binary, c=context symbol, m=string | ||
| / examples: | ||
| / eodtime.init[enlist[`log]!enlist logdep] | ||
| / eodtime.init[`log`rolltimezone!(logdep;`$"Europe/London")] | ||
| if[99h<>type deps; | ||
| '"di.eodtime: deps must be a dict with `log key"]; | ||
|
alowrydi marked this conversation as resolved.
|
||
| if[not `log in key deps; | ||
| '"di.eodtime: log dependency is required; pass at minimum `info!{[c;m]} keyed on `log"]; | ||
| if[99h<>type deps`log; | ||
| '"di.eodtime: log value must be a dict; pass at minimum `info!{[c;m]}"]; | ||
| if[not `info in key deps`log; | ||
| '"di.eodtime: log dict must have at minimum an `info key; got: ",(", " sv string key deps`log)]; | ||
| .z.m.loginfo:(deps`log)`info; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only the |
||
| .z.m.rolltimezone:$[`rolltimezone in key deps;deps`rolltimezone;`$"GMT"]; | ||
| .z.m.datatimezone:$[`datatimezone in key deps;deps`datatimezone;`$"GMT"]; | ||
| .z.m.rolltimeoffset:$[`rolltimeoffset in key deps;deps`rolltimeoffset;0D00:00:00.000]; | ||
| .z.m.dailyadj:getdailyadjustment[]; | ||
| .z.m.d:getday[.z.p]; | ||
| .z.m.nextroll:getroll[.z.p]; | ||
| .z.m.loginfo[`eodtime;"initialised with rolltimezone=",string[.z.m.rolltimezone]," datatimezone=",string[.z.m.datatimezone]," rolltimeoffset=",string .z.m.rolltimeoffset]; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| / end-of-day time management - date resolution, roll scheduling and data timestamp adjustment | ||
|
|
||
| tz:use`di.tz | ||
|
|
||
| \l ::eodtime.q | ||
|
|
||
| export:([init;getd;getnextroll;getdailyadj;getroll;getdailyadjustment;setnextroll;setdailyadj;setd]) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| action,ms,bytes,lang,code,repeat,minver,comment | ||
| comment,,,,,,,setup - load module and initialise with gmt defaults and log dep | ||
| before,0,0,q,eodtime:use`di.eodtime,1,1,load di.eodtime module | ||
| before,0,0,q,logdep:`info`warn`error!({[c;m]};{[c;m]};{[c;m]}),1,1,silent no-op log mock - binary {[c;m]} matches the log contract | ||
| before,0,0,q,eodtime.init[`rolltimezone`datatimezone`rolltimeoffset`log!(`$"GMT";`$"GMT";0D00:00:00.000;logdep)],1,1,init with gmt defaults and log dep | ||
|
|
||
| comment,,,,,,,getd | ||
| true,0,0,q,-14h=type eodtime.getd[],1,1,getd returns date type | ||
|
|
||
| comment,,,,,,,getnextroll | ||
| true,0,0,q,-12h=type eodtime.getnextroll[],1,1,getnextroll returns timestamp type | ||
| true,0,0,q,eodtime.getnextroll[]>.z.p,1,1,getnextroll returns future timestamp | ||
|
|
||
| comment,,,,,,,getdailyadj | ||
| true,0,0,q,-16h=type eodtime.getdailyadj[],1,1,getdailyadj returns timespan type | ||
| true,0,0,q,0D=eodtime.getdailyadj[],1,1,getdailyadj returns 0D for gmt datatimezone | ||
|
|
||
| comment,,,,,,,getdailyadjustment | ||
| true,0,0,q,-16h=type eodtime.getdailyadjustment[],1,1,getdailyadjustment returns timespan type | ||
| true,0,0,q,0D=eodtime.getdailyadjustment[],1,1,getdailyadjustment returns 0D for gmt datatimezone | ||
|
|
||
| comment,,,,,,,getroll - gmt zero offset | ||
| true,0,0,q,-12h=type eodtime.getroll[2025.01.01D12:00:00.000000000],1,1,getroll returns timestamp type | ||
| true,0,0,q,2025.01.02D00:00:00.000000000=eodtime.getroll[2025.01.01D12:00:00.000000000],1,1,getroll returns next midnight for gmt zero offset | ||
|
|
||
| comment,,,,,,,getroll - gmt with rolltimeoffset | ||
| run,0,0,q,eodtime.init[`rolltimezone`datatimezone`rolltimeoffset`log!(`$"GMT";`$"GMT";0D17:00:00.000;logdep)],1,1,reinit with 5pm gmt roll time | ||
| true,0,0,q,2025.01.01D17:00:00.000000000=eodtime.getroll[2025.01.01D12:00:00.000000000],1,1,getroll returns todays 5pm when before roll time | ||
| true,0,0,q,2025.01.02D17:00:00.000000000=eodtime.getroll[2025.01.01D18:00:00.000000000],1,1,getroll returns next day 5pm when past roll time | ||
|
|
||
| comment,,,,,,,setnextroll | ||
| run,0,0,q,eodtime.init[`rolltimezone`datatimezone`rolltimeoffset`log!(`$"GMT";`$"GMT";0D00:00:00.000;logdep)],1,1,reinit with gmt defaults | ||
| run,0,0,q,eodtime.setnextroll[2025.06.01D00:00:00.000000000],1,1,setnextroll does not error | ||
| true,0,0,q,2025.06.01D00:00:00.000000000=eodtime.getnextroll[],1,1,getnextroll reflects setnextroll | ||
|
|
||
| comment,,,,,,,setdailyadj | ||
| run,0,0,q,eodtime.setdailyadj[0D01:00:00.000000000],1,1,setdailyadj does not error | ||
| true,0,0,q,0D01:00:00.000000000=eodtime.getdailyadj[],1,1,getdailyadj reflects setdailyadj | ||
|
|
||
| comment,,,,,,,setd | ||
| run,0,0,q,eodtime.setd[2025.06.01],1,1,setd does not error | ||
| true,0,0,q,2025.06.01=eodtime.getd[],1,1,getd reflects setd | ||
|
|
||
| comment,,,,,,,utc-equivalent timezone shortcuts (GMT/UTC/Etc/GMT) | ||
| run,0,0,q,eodtime.init[`rolltimezone`datatimezone`rolltimeoffset`log!(`$"UTC";`$"Etc/GMT";0D00:00:00.000;logdep)],1,1,reinit with UTC/Etc/GMT shortcuts | ||
| true,0,0,q,0D=eodtime.getdailyadjustment[],1,1,Etc/GMT datatimezone returns 0D without lookup | ||
| true,0,0,q,2025.01.02D00:00:00.000000000=eodtime.getroll[2025.01.01D12:00:00.000000000],1,1,UTC rolltimezone returns correct roll | ||
|
|
||
| comment,,,,,,,non-gmt rolltimezone (Europe/London) | ||
| run,0,0,q,eodtime.init[`rolltimezone`datatimezone`rolltimeoffset`log!(`$"Europe/London";`$"GMT";0D00:00:00.000;logdep)],1,1,reinit with London rolltimezone | ||
| true,0,0,q,-12h=type eodtime.getroll[2025.01.01D12:00:00.000000000],1,1,getroll returns timestamp type for non-gmt rolltimezone | ||
| true,0,0,q,2025.01.02D00:00:00.000000000=eodtime.getroll[2025.01.01D12:00:00.000000000],1,1,getroll correct for london winter (utc+0) | ||
| true,0,0,q,2025.07.01D23:00:00.000000000=eodtime.getroll[2025.07.01D12:00:00.000000000],1,1,getroll correct for london summer (utc+1 - midnight local is 23:00 utc) | ||
|
|
||
| comment,,,,,,,getroll - dst transition overnight (europe/london clocks go back 2025.10.26 01:00 utc) | ||
| run,0,0,q,eodtime.init[`rolltimezone`datatimezone`rolltimeoffset`log!(`$"Europe/London";`$"GMT";0D05:00:00.000;logdep)],1,1,reinit with 5am london roll time | ||
| true,0,0,q,2025.10.26D05:00:00.000000000=eodtime.getroll[2025.10.25D12:00:00.000000000],1,1,rollover uses tomorrows post-transition offset (gmt) not todays bst offset | ||
|
|
||
| comment,,,,,,,non-gmt datatimezone (Europe/London - DST aware) | ||
| run,0,0,q,eodtime.init[`rolltimezone`datatimezone`rolltimeoffset`log!(`$"GMT";`$"Europe/London";0D00:00:00.000;logdep)],1,1,reinit with London datatimezone | ||
| true,0,0,q,-16h=type eodtime.getdailyadjustment[],1,1,Europe/London datatimezone returns timespan type | ||
| true,0,0,q,0D<=eodtime.getdailyadjustment[],1,1,Europe/London datatimezone returns non-negative offset | ||
|
|
||
| comment,,,,,,,init - empty config (just log dep) applies all defaults | ||
| run,0,0,q,eodtime.init[enlist[`log]!enlist logdep],1,1,init with just log dep applies all defaults | ||
| true,0,0,q,0D=eodtime.getdailyadj[],1,1,default datatimezone (GMT) produces zero daily adjustment | ||
| true,0,0,q,0D=eodtime.getdailyadjustment[],1,1,default datatimezone (GMT) produces zero computed adjustment | ||
| true,0,0,q,2025.01.02D00:00:00.000000000=eodtime.getroll[2025.01.01D12:00:00.000000000],1,1,default rolltimeoffset (0D) gives midnight roll | ||
|
|
||
| comment,,,,,,,init - non-dict configs throws | ||
| fail,0,0,q,eodtime.init[(::)],1,1,errors when configs is not a dictionary | ||
|
|
||
| comment,,,,,,,error cases | ||
| fail,0,0,q,eodtime.getroll[`notvalid],1,1,getroll throws on non-timestamp input | ||
|
|
||
| comment,,,,,,,init - dep validation | ||
| fail,0,0,q,eodtime.init[()!()],1,1,errors when log dependency is missing | ||
| fail,0,0,q,eodtime.init[enlist[`log]!enlist 42],1,1,errors when log value is not a dictionary | ||
| run,0,0,q,eodtime.init[enlist[`log]!enlist `info`warn!(logdep`info;logdep`warn)],1,1,init succeeds with info and warn but no error key - only info is required | ||
| run,0,0,q,.test.err:@[{eodtime.init[()!()]};(::);{x}],1,1,capture error string from init with missing log dep | ||
| true,0,0,q,.test.err like "di.eodtime:*",1,1,error is prefixed di.eodtime: | ||
|
|
||
| comment,,,,,,,init - accepts any dict already shaped to the binary {[c;m]} contract (e.g. di.log's logdict) | ||
| run,0,0,q,sixlvllog:`trace`debug`info`warn`error`fatal!({[c;m]};{[c;m]};{[c;m]};{[c;m]};{[c;m]};{[c;m]}),1,1,hand-built six-level dict matching di.log's logdict shape | ||
| run,0,0,q,eodtime.init[`log`rolltimezone!(sixlvllog;`$"GMT")],1,1,superset log dict accepted as-is - only info/warn/error are used | ||
|
|
||
|
alowrydi marked this conversation as resolved.
|
||
| comment,,,,,,,log call verification - capturing logger sees init message with binary {[c;m]} args | ||
| run,0,0,q,caplog:`info`warn`error!({[c;m] `.test.cap upsert(`info;m)};{[c;m] `.test.cap upsert(`warn;m)};{[c;m] `.test.cap upsert(`error;m)}),1,1,capturing log mock - binary {[c;m]} | ||
| run,0,0,q,.test.cap:([] fn:`symbol$();msg:()),1,1,initialise log capture table | ||
| run,0,0,q,eodtime.init[enlist[`log]!enlist caplog],1,1,init with capturing logger | ||
| true,0,0,q,1=count select from .test.cap where fn=`info,1,1,one info entry captured on init | ||
| true,0,0,q,any (.test.cap`msg) like "initialised*",1,1,log message confirms initialisation | ||
Uh oh!
There was an error while loading. Please reload this page.