jspurefix 5.11.1 → 5.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +13 -1
  2. package/dist/buffer/fixml/fixml-parser.js +1 -1
  3. package/dist/buffer/fixml/fixml-parser.js.map +1 -1
  4. package/dist/config/empty-log-factory.d.ts +2 -2
  5. package/dist/config/empty-log-factory.js +1 -1
  6. package/dist/config/empty-log-factory.js.map +1 -1
  7. package/dist/config/get-js-fx-logger.d.ts +2 -2
  8. package/dist/config/get-js-fx-logger.js.map +1 -1
  9. package/dist/config/js-fix-logger-factory.d.ts +2 -2
  10. package/dist/config/js-fix-logger-factory.js.map +1 -1
  11. package/dist/config/js-fix-logger.d.ts +9 -8
  12. package/dist/config/js-fix-logger.js +4 -4
  13. package/dist/config/js-fix-logger.js.map +1 -1
  14. package/dist/config/js-fix-winston-log-factory.d.ts +2 -2
  15. package/dist/config/js-fix-winston-log-factory.js +2 -2
  16. package/dist/config/js-fix-winston-log-factory.js.map +1 -1
  17. package/dist/config/winston-logger.d.ts +5 -2
  18. package/dist/config/winston-logger.js +57 -9
  19. package/dist/config/winston-logger.js.map +1 -1
  20. package/dist/dictionary/fragment-safety.d.ts +26 -0
  21. package/dist/dictionary/fragment-safety.js +154 -0
  22. package/dist/dictionary/fragment-safety.js.map +1 -0
  23. package/dist/dictionary/index.d.ts +1 -0
  24. package/dist/dictionary/index.js +1 -0
  25. package/dist/dictionary/index.js.map +1 -1
  26. package/dist/runtime/make-config.js +1 -1
  27. package/dist/runtime/make-config.js.map +1 -1
  28. package/dist/runtime/session-launcher.js +1 -1
  29. package/dist/runtime/session-launcher.js.map +1 -1
  30. package/dist/sample/http/oms/http-client.js +1 -1
  31. package/dist/sample/http/oms/http-client.js.map +1 -1
  32. package/dist/sample/http/oms/http-server.js +1 -1
  33. package/dist/sample/http/oms/http-server.js.map +1 -1
  34. package/dist/sample/tcp/qf-md/md-client.js +1 -1
  35. package/dist/sample/tcp/qf-md/md-client.js.map +1 -1
  36. package/dist/sample/tcp/qf-md/md-server.js +1 -1
  37. package/dist/sample/tcp/qf-md/md-server.js.map +1 -1
  38. package/dist/sample/tcp/recovering-skeleton/respawn-acceptor.js +1 -1
  39. package/dist/sample/tcp/recovering-skeleton/respawn-acceptor.js.map +1 -1
  40. package/dist/sample/tcp/recovering-skeleton/skeleton-client.js +1 -1
  41. package/dist/sample/tcp/recovering-skeleton/skeleton-client.js.map +1 -1
  42. package/dist/sample/tcp/recovering-skeleton/skeleton-server.js +1 -1
  43. package/dist/sample/tcp/recovering-skeleton/skeleton-server.js.map +1 -1
  44. package/dist/sample/tcp/skeleton/skeleton-session.js +1 -1
  45. package/dist/sample/tcp/skeleton/skeleton-session.js.map +1 -1
  46. package/dist/sample/tcp/trade-capture/trade-capture-client.js +1 -1
  47. package/dist/sample/tcp/trade-capture/trade-capture-client.js.map +1 -1
  48. package/dist/sample/tcp/trade-capture/trade-capture-server.js +1 -1
  49. package/dist/sample/tcp/trade-capture/trade-capture-server.js.map +1 -1
  50. package/dist/store/fix-msg-memory-store.js +1 -1
  51. package/dist/store/fix-msg-memory-store.js.map +1 -1
  52. package/dist/transport/ascii/ascii-msg-transmitter.js +1 -1
  53. package/dist/transport/ascii/ascii-msg-transmitter.js.map +1 -1
  54. package/dist/transport/ascii/ascii-session.js +1 -1
  55. package/dist/transport/ascii/ascii-session.js.map +1 -1
  56. package/dist/transport/http/http-acceptor-listener.js +1 -1
  57. package/dist/transport/http/http-acceptor-listener.js.map +1 -1
  58. package/dist/transport/http/http-acceptor.js +2 -2
  59. package/dist/transport/http/http-acceptor.js.map +1 -1
  60. package/dist/transport/http/http-initiator.js +1 -1
  61. package/dist/transport/http/http-initiator.js.map +1 -1
  62. package/dist/transport/http/http-json-sample-adapter.js +1 -1
  63. package/dist/transport/http/http-json-sample-adapter.js.map +1 -1
  64. package/dist/transport/session/fix-session.js +3 -3
  65. package/dist/transport/session/fix-session.js.map +1 -1
  66. package/dist/transport/session/session-registry.js +1 -1
  67. package/dist/transport/session/session-registry.js.map +1 -1
  68. package/dist/transport/tcp/recovering-tcp-initiator.js +1 -1
  69. package/dist/transport/tcp/recovering-tcp-initiator.js.map +1 -1
  70. package/dist/transport/tcp/tcp-acceptor-listener.js +2 -2
  71. package/dist/transport/tcp/tcp-acceptor-listener.js.map +1 -1
  72. package/dist/transport/tcp/tcp-acceptor.js +2 -2
  73. package/dist/transport/tcp/tcp-acceptor.js.map +1 -1
  74. package/dist/transport/tcp/tcp-initiator-connector.js +2 -2
  75. package/dist/transport/tcp/tcp-initiator-connector.js.map +1 -1
  76. package/dist/transport/tcp/tcp-initiator.js +1 -1
  77. package/dist/transport/tcp/tcp-initiator.js.map +1 -1
  78. package/docs/instrumentation.md +360 -0
  79. package/docs/scattered-components.md +280 -0
  80. package/jsfix.test_client.txt +62 -62
  81. package/jsfix.test_server.txt +72 -72
  82. package/package.json +1 -1
  83. package/src/buffer/fixml/fixml-parser.ts +1 -1
  84. package/src/config/empty-log-factory.ts +2 -2
  85. package/src/config/get-js-fx-logger.ts +2 -2
  86. package/src/config/js-fix-logger-factory.ts +8 -2
  87. package/src/config/js-fix-logger.ts +23 -8
  88. package/src/config/js-fix-winston-log-factory.ts +3 -3
  89. package/src/config/winston-logger.ts +93 -10
  90. package/src/dictionary/fragment-safety.ts +225 -0
  91. package/src/dictionary/index.ts +1 -0
  92. package/src/runtime/make-config.ts +1 -1
  93. package/src/runtime/session-launcher.ts +1 -1
  94. package/src/sample/http/oms/http-client.ts +1 -1
  95. package/src/sample/http/oms/http-server.ts +1 -1
  96. package/src/sample/tcp/qf-md/md-client.ts +1 -1
  97. package/src/sample/tcp/qf-md/md-server.ts +1 -1
  98. package/src/sample/tcp/recovering-skeleton/respawn-acceptor.ts +2 -1
  99. package/src/sample/tcp/recovering-skeleton/skeleton-client.ts +1 -1
  100. package/src/sample/tcp/recovering-skeleton/skeleton-server.ts +1 -1
  101. package/src/sample/tcp/skeleton/skeleton-session.ts +1 -1
  102. package/src/sample/tcp/trade-capture/trade-capture-client.ts +2 -1
  103. package/src/sample/tcp/trade-capture/trade-capture-server.ts +2 -1
  104. package/src/store/fix-msg-memory-store.ts +2 -1
  105. package/src/transport/ascii/ascii-msg-transmitter.ts +2 -1
  106. package/src/transport/ascii/ascii-session.ts +2 -1
  107. package/src/transport/http/http-acceptor-listener.ts +2 -1
  108. package/src/transport/http/http-acceptor.ts +2 -1
  109. package/src/transport/http/http-initiator.ts +2 -1
  110. package/src/transport/http/http-json-sample-adapter.ts +1 -1
  111. package/src/transport/session/fix-session.ts +2 -1
  112. package/src/transport/session/session-registry.ts +1 -1
  113. package/src/transport/tcp/recovering-tcp-initiator.ts +2 -1
  114. package/src/transport/tcp/tcp-acceptor-listener.ts +4 -2
  115. package/src/transport/tcp/tcp-acceptor.ts +2 -1
  116. package/src/transport/tcp/tcp-initiator-connector.ts +4 -2
  117. package/src/transport/tcp/tcp-initiator.ts +2 -1
@@ -0,0 +1,225 @@
1
+ import {
2
+ ContainedComponentField,
3
+ ContainedField,
4
+ ContainedFieldType,
5
+ ContainedGroupField,
6
+ ContainedSimpleField,
7
+ IContainedSet
8
+ } from './contained'
9
+ import { FixDefinitions } from './definition'
10
+
11
+ /**
12
+ * Static analysis of a dictionary, asking one question: if a component's tags arrived
13
+ * scattered through a message rather than adjacently, could this dictionary still say
14
+ * unambiguously which component each tag belongs to?
15
+ *
16
+ * The segment parser normally answers that from *position* - a tag between the first and
17
+ * last tag of a component belongs to it. A counterparty that emits a component's tags
18
+ * non-adjacently breaks the inference, and the tags themselves become the only evidence
19
+ * left. That works whenever the children of one set own disjoint tags, which FIX's tag
20
+ * numbering conventions (Underlying*, Leg*, NestedParties2/3) exist to guarantee, but a
21
+ * house dictionary is under no obligation to honour them.
22
+ *
23
+ * See docs/scattered-components.md. Nothing in the engine consumes this yet - it is a
24
+ * diagnostic run against a dictionary to find out whether the assumption holds before any
25
+ * code is written that depends on it.
26
+ */
27
+
28
+ export enum FragmentSafetyCode {
29
+ /**
30
+ * two children of one set both claim the same tag, so a scattered instance of either
31
+ * could not be attributed to one of them by tag alone
32
+ */
33
+ SiblingTagCollision = 'sibling-tag-collision',
34
+ /**
35
+ * a component owns no tag at its own level, so a scattered instance leaves no evidence
36
+ * it was ever present
37
+ */
38
+ UnclaimableComponent = 'unclaimable-component'
39
+ }
40
+
41
+ export interface IFragmentSafetyFinding {
42
+ readonly code: FragmentSafetyCode
43
+ /**
44
+ * dotted path to the set the finding is about, from the message it was first reached
45
+ * through e.g. 'NewOrderSingle.Instrument'
46
+ */
47
+ readonly path: string
48
+ /**
49
+ * name of the set whose children collide, or of the unclaimable component
50
+ */
51
+ readonly set: string
52
+ /**
53
+ * the contended tag, or 0 for an unclaimable component
54
+ */
55
+ readonly tag: number
56
+ /**
57
+ * names of the children of `set` that each claim `tag`
58
+ */
59
+ readonly owners: string[]
60
+ }
61
+
62
+ export function describeFinding (f: IFragmentSafetyFinding): string {
63
+ switch (f.code) {
64
+ case FragmentSafetyCode.SiblingTagCollision:
65
+ return `${f.path}: tag ${f.tag} is claimed by ${f.owners.join(' and ')}`
66
+ case FragmentSafetyCode.UnclaimableComponent:
67
+ return `${f.path}: owns no tag of its own`
68
+ default:
69
+ return f.path
70
+ }
71
+ }
72
+
73
+ export class FragmentSafety {
74
+ private readonly findings: IFragmentSafetyFinding[] = []
75
+ private readonly analysed = new Set<IContainedSet>()
76
+ private readonly owned = new Map<IContainedSet, number[]>()
77
+
78
+ /**
79
+ * tags a set can claim at its own level - its simple fields, the same from any
80
+ * component nested below it, and the NumInGroup tag of any group it contains.
81
+ *
82
+ * a group's *interior* is deliberately excluded. a repeating group is the one
83
+ * self describing construct in tag value FIX, so its instances are always delimiter
84
+ * framed and contiguous, and its member tags are never evidence about the level above.
85
+ * this is the same distinction `flattenedTag` does not draw.
86
+ */
87
+ public ownTags (set: IContainedSet): number[] {
88
+ const memo = this.owned.get(set)
89
+ if (memo) return memo
90
+ // seed before recursing so a self referencing dictionary terminates
91
+ this.owned.set(set, [])
92
+ const tags: number[] = []
93
+ for (const field of set.fields) {
94
+ switch (field.type) {
95
+ case ContainedFieldType.Simple: {
96
+ tags.push((field as ContainedSimpleField).definition.tag)
97
+ break
98
+ }
99
+ case ContainedFieldType.Component: {
100
+ const cf = field as ContainedComponentField
101
+ for (const t of this.ownTags(cf.definition)) {
102
+ tags.push(t)
103
+ }
104
+ break
105
+ }
106
+ case ContainedFieldType.Group: {
107
+ const gf = field as ContainedGroupField
108
+ const nof = gf.definition.noOfField
109
+ if (nof) {
110
+ tags.push(nof.tag)
111
+ }
112
+ break
113
+ }
114
+ default:
115
+ break
116
+ }
117
+ }
118
+ this.owned.set(set, tags)
119
+ return tags
120
+ }
121
+
122
+ /**
123
+ * every message in the dictionary, and every component and group reachable from one,
124
+ * each analysed once however many messages reach it
125
+ */
126
+ public static analyse (definitions: FixDefinitions): IFragmentSafetyFinding[] {
127
+ const instance = new FragmentSafety()
128
+ // the message map is keyed by name, msgType and abbreviation, so walk distinct sets
129
+ const seen = new Set<IContainedSet>()
130
+ for (const message of definitions.message.values()) {
131
+ if (seen.has(message)) continue
132
+ seen.add(message)
133
+ instance.walk(message, message.name)
134
+ }
135
+ return instance.findings
136
+ }
137
+
138
+ /**
139
+ * a single set and everything below it, for a dictionary fragment under test
140
+ */
141
+ public static analyseSet (set: IContainedSet, path?: string): IFragmentSafetyFinding[] {
142
+ const instance = new FragmentSafety()
143
+ instance.walk(set, path ?? set.name)
144
+ return instance.findings
145
+ }
146
+
147
+ private walk (set: IContainedSet, path: string): void {
148
+ if (this.analysed.has(set)) return
149
+ this.analysed.add(set)
150
+ this.checkSiblings(set, path)
151
+ for (const field of set.fields) {
152
+ switch (field.type) {
153
+ case ContainedFieldType.Component: {
154
+ const cf = field as ContainedComponentField
155
+ this.checkClaimable(cf, `${path}.${cf.name}`)
156
+ this.walk(cf.definition, `${path}.${cf.name}`)
157
+ break
158
+ }
159
+ case ContainedFieldType.Group: {
160
+ // the instance body of a group is a level in its own right, and everything
161
+ // said about scattering above applies again inside it
162
+ const gf = field as ContainedGroupField
163
+ this.walk(gf.definition, `${path}.${gf.name}`)
164
+ break
165
+ }
166
+ default:
167
+ break
168
+ }
169
+ }
170
+ }
171
+
172
+ private checkClaimable (cf: ContainedComponentField, path: string): void {
173
+ if (this.ownTags(cf.definition).length > 0) return
174
+ this.findings.push({
175
+ code: FragmentSafetyCode.UnclaimableComponent,
176
+ path,
177
+ set: cf.name,
178
+ tag: 0,
179
+ owners: []
180
+ })
181
+ }
182
+
183
+ private checkSiblings (set: IContainedSet, path: string): void {
184
+ // tag -> the children of this set claiming it. a tag reaching two children is what
185
+ // makes a scattered instance unattributable
186
+ const claims = new Map<number, string[]>()
187
+ for (const field of set.fields) {
188
+ for (const tag of this.claimsOf(field)) {
189
+ const owners = claims.get(tag)
190
+ if (owners) {
191
+ if (!owners.includes(field.name)) {
192
+ owners.push(field.name)
193
+ }
194
+ } else {
195
+ claims.set(tag, [field.name])
196
+ }
197
+ }
198
+ }
199
+ for (const [tag, owners] of claims) {
200
+ if (owners.length < 2) continue
201
+ this.findings.push({
202
+ code: FragmentSafetyCode.SiblingTagCollision,
203
+ path,
204
+ set: set.name,
205
+ tag,
206
+ owners
207
+ })
208
+ }
209
+ }
210
+
211
+ private claimsOf (field: ContainedField): number[] {
212
+ switch (field.type) {
213
+ case ContainedFieldType.Simple:
214
+ return [(field as ContainedSimpleField).definition.tag]
215
+ case ContainedFieldType.Component:
216
+ return this.ownTags((field as ContainedComponentField).definition)
217
+ case ContainedFieldType.Group: {
218
+ const nof = (field as ContainedGroupField).definition.noOfField
219
+ return nof ? [nof.tag] : []
220
+ }
221
+ default:
222
+ return []
223
+ }
224
+ }
225
+ }
@@ -3,4 +3,5 @@ export * from './field-enum'
3
3
  export * from './contained/fields-dispatch'
4
4
  export * from './fix-parser'
5
5
  export * from './fix-versions'
6
+ export * from './fragment-safety'
6
7
  export * from './set-reduce'
@@ -25,7 +25,7 @@ export class RuntimeFactory {
25
25
  if (!type) reject(new Error('no application type in application object'))
26
26
  this.definitionFactory.getDefinitions(path,
27
27
  (t: string) => {
28
- return this.logFactory.logger(`${type}.${t}`)
28
+ return this.logFactory.logger(`${type}.${t}`, { component: t, role: type })
29
29
  }).then((definitions: FixDefinitions) => {
30
30
  const config = new JsFixConfig(this.msgFactory, definitions, description, AsciiChars.Soh, this.logFactory)
31
31
  resolve(config)
@@ -19,7 +19,7 @@ export abstract class SessionLauncher {
19
19
  acceptorConfig: string | ISessionDescription | null = null,
20
20
  private readonly loggerFactory: JsFixLoggerFactory = defaultLoggerFactory
21
21
  ) {
22
- this.logger = this.loggerFactory.logger('launcher')
22
+ this.logger = this.loggerFactory.logger('launcher', { component: 'SessionLauncher' })
23
23
  this.initiatorConfig = initiatorConfig ? this.loadConfig(initiatorConfig) : null
24
24
  this.acceptorConfig = acceptorConfig ? this.loadConfig(acceptorConfig) : null
25
25
  }
@@ -16,7 +16,7 @@ export class HttpClient extends FixmlSession {
16
16
  super(config)
17
17
  this.logReceivedMsgs = true
18
18
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
19
- this.logger = config.logFactory.logger(`${this.me}`)
19
+ this.logger = config.logFactory.logger(`${this.me}`, { component: 'HttpClient', app: this.me })
20
20
  }
21
21
 
22
22
  protected onApplicationMsg (msgType: string, view: MsgView): void {
@@ -16,7 +16,7 @@ export class HttpServer extends FixmlSession {
16
16
  super(config)
17
17
  this.logReceivedMsgs = true
18
18
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
19
- this.logger = config.logFactory.logger(`${this.me}`)
19
+ this.logger = config.logFactory.logger(`${this.me}`, { component: 'HttpServer', app: this.me })
20
20
  }
21
21
 
22
22
  protected onApplicationMsg (msgType: string, view: MsgView): void {
@@ -16,7 +16,7 @@ export class MDClient extends AsciiSession {
16
16
  super(config)
17
17
  this.logReceivedMsgs = true
18
18
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
19
- this.logger = config.logFactory.logger(`${this.me}:MDClient`)
19
+ this.logger = config.logFactory.logger(`${this.me}:MDClient`, { component: 'MDClient', app: this.me })
20
20
  }
21
21
 
22
22
  protected onApplicationMsg (_: string, view: MsgView): void {
@@ -16,7 +16,7 @@ export class MDServer extends AsciiSession {
16
16
  constructor (@inject('IJsFixConfig') public readonly config: IJsFixConfig) {
17
17
  super(config)
18
18
  this.logReceivedMsgs = true
19
- this.logger = config.logFactory.logger(`${this.me}:MDServer`)
19
+ this.logger = config.logFactory.logger(`${this.me}:MDServer`, { component: 'MDServer', app: this.me })
20
20
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
21
21
  }
22
22
 
@@ -13,7 +13,8 @@ export class RespawnAcceptor extends FixEntity {
13
13
 
14
14
  constructor (@inject('IJsFixConfig') public readonly config: IJsFixConfig) {
15
15
  super(config)
16
- this.logger = config.logFactory.logger('RespawnAcceptor')
16
+ this.logger = config.logFactory.logger('RespawnAcceptor',
17
+ { component: 'RespawnAcceptor', role: 'acceptor' })
17
18
  }
18
19
 
19
20
  // if acceptor errors e.g. via a forced connection drop, then respawn
@@ -13,7 +13,7 @@ export class SkeletonClient extends AsciiSession {
13
13
  super(config)
14
14
  this.logReceivedMsgs = true
15
15
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
16
- this.logger = config.logFactory.logger(`${this.me}`)
16
+ this.logger = config.logFactory.logger(`${this.me}`, { component: 'SkeletonClient', app: this.me })
17
17
  }
18
18
 
19
19
  protected onApplicationMsg (msgType: string, view: MsgView): void {
@@ -13,7 +13,7 @@ export class SkeletonServer extends AsciiSession {
13
13
  super(config)
14
14
  this.logReceivedMsgs = true
15
15
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
16
- this.logger = config.logFactory.logger(`${this.me}`)
16
+ this.logger = config.logFactory.logger(`${this.me}`, { component: 'SkeletonServer', app: this.me })
17
17
  }
18
18
 
19
19
  protected onApplicationMsg (msgType: string, _: MsgView): void {
@@ -17,7 +17,7 @@ export class SkeletonSession extends AsciiSession {
17
17
  super(config)
18
18
  this.logReceivedMsgs = true
19
19
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
20
- this.logger = config.logFactory.logger(`${this.me}`)
20
+ this.logger = config.logFactory.logger(`${this.me}`, { component: 'SkeletonSession', app: this.me })
21
21
  }
22
22
 
23
23
  protected onApplicationMsg (msgType: string, view: MsgView): void {
@@ -18,7 +18,8 @@ export class TradeCaptureClient extends AsciiSession {
18
18
  this.logReceivedMsgs = true
19
19
  this.reports = new Map<string, ITradeCaptureReport>()
20
20
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
21
- this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`)
21
+ this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`,
22
+ { component: 'TradeCaptureClient', app: this.me })
22
23
  }
23
24
 
24
25
  protected onApplicationMsg (msgType: string, view: MsgView): void {
@@ -18,7 +18,8 @@ export class TradeCaptureServer extends AsciiSession {
18
18
  constructor (public readonly config: IJsFixConfig) {
19
19
  super(config)
20
20
  this.logReceivedMsgs = true
21
- this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`)
21
+ this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`,
22
+ { component: 'TradeCaptureServer', app: this.me })
22
23
  this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
23
24
  }
24
25
 
@@ -20,7 +20,8 @@ export class FixMsgMemoryStore implements IFixMsgStore {
20
20
  ]
21
21
 
22
22
  public constructor (public readonly id: string, public readonly config: IJsFixConfig) {
23
- this.logger = config.logFactory.logger(`${this.id}:FixMsgMemoryStore`)
23
+ this.logger = config.logFactory.logger(`${this.id}:FixMsgMemoryStore`,
24
+ { component: 'FixMsgMemoryStore', store: this.id })
24
25
  this.setExcMsgType([])
25
26
  }
26
27
 
@@ -39,7 +39,8 @@ export class AsciiMsgTransmitter extends MsgTransmitter {
39
39
  */
40
40
  private reportUnknownFields (config: IJsFixConfig): void {
41
41
  const name = config.description.application?.name ?? 'na'
42
- const logger = config.logFactory.logger(`${name}:encoder`)
42
+ const logger = config.logFactory.logger(`${name}:encoder`,
43
+ { component: 'AsciiMsgTransmitter', app: name })
43
44
  const reported = new Set<string>()
44
45
  this.encoder.onUnknownField = (fieldName: string, setName: string) => {
45
46
  const key = `${setName}.${fieldName}`
@@ -662,7 +662,8 @@ export abstract class AsciiSession extends FixSession {
662
662
 
663
663
  // every session on a wildcard listener shared one logger name until now, which
664
664
  // makes a multi-client server log impossible to follow
665
- this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`)
665
+ this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`,
666
+ { component: 'FixSession', app: this.me, peer: peerCompId })
666
667
 
667
668
  this.sessionId = new SessionId(
668
669
  this.config.description.BeginString,
@@ -15,7 +15,8 @@ export class HttpAcceptorListener extends FixEntity {
15
15
 
16
16
  async start (): Promise<any> {
17
17
  return new Promise<any>(async (resolve, reject) => {
18
- const logger = this.config.logFactory.logger('acceptor')
18
+ const logger = this.config.logFactory.logger('acceptor',
19
+ { component: 'HttpAcceptorListener', role: 'acceptor' })
19
20
  const sessionContainer = this.config.sessionContainer
20
21
  if (!sessionContainer.isRegistered(DITokens.FixSession)) {
21
22
  reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))
@@ -22,7 +22,8 @@ export class HttpAcceptor extends FixAcceptor {
22
22
 
23
23
  constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {
24
24
  super(config?.description?.application ?? null)
25
- this.logger = config.logFactory.logger(`${config?.description?.application?.name}:HttpAcceptor`)
25
+ this.logger = config.logFactory.logger(`${config?.description?.application?.name}:HttpAcceptor`,
26
+ { component: 'HttpAcceptor', app: config?.description?.application?.name, role: 'acceptor' })
26
27
  this.logger.info('creating http server')
27
28
  this.router = express.Router()
28
29
  this.router.use(bodyParser.json())
@@ -11,7 +11,8 @@ export class HttpInitiator extends FixEntity {
11
11
  logger: IJsFixLogger
12
12
  constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {
13
13
  super(config)
14
- this.logger = config.logFactory.logger('initiator')
14
+ this.logger = config.logFactory.logger('initiator',
15
+ { component: 'HttpInitiator', role: 'initiator' })
15
16
  }
16
17
 
17
18
  async start (): Promise<any> {
@@ -13,7 +13,7 @@ export class HttpJsonSampleAdapter implements IHttpAdapter {
13
13
  private token: string | null = null
14
14
  private readonly routes: Map<string, IHtmlRoute> = new Map<string, IHtmlRoute>()
15
15
  constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {
16
- this.logger = config.logFactory.logger('http.adapter')
16
+ this.logger = config.logFactory.logger('http.adapter', { component: 'HttpJsonSampleAdapter' })
17
17
  const routes = this.routes
18
18
  const options = config?.description?.application?.http?.options
19
19
  if (!options) {
@@ -61,7 +61,8 @@ export abstract class FixSession extends events.EventEmitter {
61
61
  heartBeat: config.description.HeartBtInt,
62
62
  lastPeerMsgSeqNum: config.description.LastReceivedSeqNum
63
63
  })
64
- this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`)
64
+ this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`,
65
+ { component: 'FixSession', app: this.me, role: description?.application?.type })
65
66
  this.initiator = description?.application?.type === 'initiator'
66
67
  this.acceptor = !this.initiator
67
68
  this.checkMsgIntegrity = this.acceptor
@@ -53,7 +53,7 @@ export class SessionRegistry implements ISessionRegistry {
53
53
  private readonly logger: IJsFixLogger | null
54
54
 
55
55
  constructor (logFactory?: JsFixLoggerFactory) {
56
- this.logger = logFactory?.logger('SessionRegistry') ?? null
56
+ this.logger = logFactory?.logger('SessionRegistry', { component: 'SessionRegistry' }) ?? null
57
57
  }
58
58
 
59
59
  public get count (): number {
@@ -39,7 +39,8 @@ export class RecoveringTcpInitiator extends FixEntity {
39
39
  super(jsFixConfig)
40
40
  this.application = this.jsFixConfig.description.application ?? null
41
41
  const name = this.application?.name ?? 'na'
42
- this.logger = jsFixConfig.logFactory.logger(`${name}:RecoveringTcpInitiator`)
42
+ this.logger = jsFixConfig.logFactory.logger(`${name}:RecoveringTcpInitiator`,
43
+ { component: 'RecoveringTcpInitiator', app: name, role: 'initiator' })
43
44
  if (!this.application) {
44
45
  throw new Error('no application in session description.')
45
46
  }
@@ -27,7 +27,8 @@ export class TcpAcceptorListener extends FixEntity {
27
27
 
28
28
  async start (): Promise<any> {
29
29
  return await new Promise<any>(async (resolve, reject) => {
30
- const logger = this.config.logFactory.logger('acceptor')
30
+ const logger = this.config.logFactory.logger('acceptor',
31
+ { component: 'TcpAcceptorListener', role: 'acceptor' })
31
32
  const sessionContainer = this.config.sessionContainer
32
33
  if (!sessionContainer.isRegistered(DITokens.FixSession)) {
33
34
  reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))
@@ -93,7 +94,8 @@ export class TcpAcceptorListener extends FixEntity {
93
94
  */
94
95
  stop (): void {
95
96
  if (this.acceptor) {
96
- const logger = this.config.logFactory.logger('acceptor')
97
+ const logger = this.config.logFactory.logger('acceptor',
98
+ { component: 'TcpAcceptorListener', role: 'acceptor' })
97
99
  logger.info('acceptor stopping')
98
100
  this.acceptor.close(() => {
99
101
  logger.info('acceptor closed.')
@@ -18,7 +18,8 @@ export class TcpAcceptor extends FixAcceptor {
18
18
 
19
19
  constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {
20
20
  super(config.description.application ?? null)
21
- this.logger = config.logFactory.logger(`${config.description.application?.name}:TcpAcceptor`)
21
+ this.logger = config.logFactory.logger(`${config.description.application?.name}:TcpAcceptor`,
22
+ { component: 'TcpAcceptor', app: config.description.application?.name, role: 'acceptor' })
22
23
  const tlsOptions: TlsOptions | null = this.tlsOptions()
23
24
  if (tlsOptions) {
24
25
  this.tlsServer()
@@ -21,7 +21,8 @@ export class TcpInitiatorConnector extends FixEntity {
21
21
  async start (reconnectTimeout: number = 0): Promise<any> {
22
22
 
23
23
  return await new Promise<any>(async (resolve, reject) => {
24
- const logger = this.config.logFactory.logger('initiator')
24
+ const logger = this.config.logFactory.logger('initiator',
25
+ { component: 'TcpInitiatorConnector', role: 'initiator' })
25
26
  const sessionContainer = this.config.sessionContainer
26
27
  if (!sessionContainer.isRegistered(DITokens.FixSession)) {
27
28
  reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))
@@ -64,7 +65,8 @@ export class TcpInitiatorConnector extends FixEntity {
64
65
  }
65
66
 
66
67
  async connect (initiatorSession: FixSession): Promise<any> {
67
- const logger = this.config.logFactory.logger('initiator')
68
+ const logger = this.config.logFactory.logger('initiator',
69
+ { component: 'TcpInitiatorConnector', role: 'initiator' })
68
70
  const initiator: FixInitiator = this.config.sessionContainer.resolve<FixInitiator>(TcpInitiator)
69
71
  logger.info('connecting ...')
70
72
  const initiatorTransport: MsgTransport = await initiator.connect(this.connectTimeoutSecs)
@@ -33,7 +33,8 @@ export class TcpInitiator extends FixInitiator {
33
33
  constructor (@inject(DITokens.IJsFixConfig) public readonly jsFixConfig: IJsFixConfig) {
34
34
  super(jsFixConfig.description.application ?? null)
35
35
  const name = this.application?.name ?? 'initiator'
36
- this.logger = jsFixConfig.logFactory.logger(`${name}:TcpInitiator`)
36
+ this.logger = jsFixConfig.logFactory.logger(`${name}:TcpInitiator`,
37
+ { component: 'TcpInitiator', app: name, role: 'initiator' })
37
38
  if (!this.application) {
38
39
  throw new Error('no application in session description.')
39
40
  }