Skip to content

Commit c07bf1c

Browse files
authored
Merge pull request #29 from corda/logging-cordapp
2 parents c6d3860 + 766cb73 commit c07bf1c

File tree

29 files changed

+1194
-17
lines changed

29 files changed

+1194
-17
lines changed

Features/README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,47 @@
33
This folder features several sample projects, each of them demonstrates different specific features of corda.
44

55
### [Blacklist -- Attachment](./attachment-blacklist):
6-
This CorDapp allows nodes to reach agreement over arbitrary strings of text, but only with parties that are not included in the blacklist uploaded to the nodes as an [attachment](https://training.corda.net/corda-details/attachments/).
6+
This CorDapp allows nodes to reach agreement over arbitrary strings of text, but only with parties that are not included in the blacklist uploaded to the nodes as an [attachment](https://training.corda.net/corda-details/attachments/).
77

88
### [Sendfile -- Attachment](./attachment-sendfile):
9-
This Cordapp shows how to upload and download an [attachment](https://training.corda.net/corda-details/attachments/) via a flow.
9+
This Cordapp shows how to upload and download an [attachment](https://training.corda.net/corda-details/attachments/) via a flow.
1010
<p align="center">
1111
<img src="./attachment-sendfile/graph.png" alt="Corda" width="700">
1212
</p>
1313

1414
### [Whistleblower -- Confidential Identity ](./confidentialIdentity-whistleblower):
15-
This CorDapp is a simple showcase of [confidential identities](https://docs.corda.net/docs/corda-os/api-identity.html#confidential-identities) (i.e. anonymous public keys).
15+
This CorDapp is a simple showcase of [confidential identities](https://docs.corda.net/docs/corda-os/api-identity.html#confidential-identities) (i.e. anonymous public keys).
1616

1717
### [Autopayroll -- CordaService](./cordaService-autopayroll):
18-
This Cordapp shows how to trigger a flow with vault update(completion of prior flows) using [CordaService](https://training.corda.net/corda-details/automation/#services) & [trackby](https://training.corda.net/corda-details/automation-solution/#track-and-notify).
18+
This Cordapp shows how to trigger a flow with vault update(completion of prior flows) using [CordaService](https://training.corda.net/corda-details/automation/#services) & [trackby](https://training.corda.net/corda-details/automation-solution/#track-and-notify).
1919
<p align="center">
2020
<img src="./cordaService-autopayroll/webpic/Business%20Logic.png" alt="Corda" width="500">
2121
</p>
2222

2323
### [Trade Reporting -- ObservableStates](./observableStates-tradereporting):
24-
This CorDapp shows how Corda's [observable states](https://docs.corda.net/docs/corda-os/4.4/tutorial-observer-nodes.html#observer-nodes) feature works. Observable states is the ability for nodes who are not participants in a transaction to still store them if the transactions are sent to them.
24+
This CorDapp shows how Corda's [observable states](https://docs.corda.net/docs/corda-os/4.4/tutorial-observer-nodes.html#observer-nodes) feature works. Observable states is the ability for nodes who are not participants in a transaction to still store them if the transactions are sent to them.
2525

2626
### [Prime Number -- Oracle](./oracle-primenumber):
2727
This CorDapp implements an [oracle service](https://training.corda.net/corda-details/oracles) that allows nodes to:
2828

2929
* Request the Nth prime number
30-
* Request the oracle's signature to prove that the number included in their transaction is actually the Nth prime number
30+
* Request the oracle's signature to prove that the number included in their transaction is actually the Nth prime number
3131

3232

3333
### [Car Insurance -- QueryableState](./queryableState-carinsurance):
34-
This CorDapp demonstrates [QueryableState](https://docs.corda.net/docs/corda-os/api-persistence.html) works in Corda. Corda allows developers to have the ability to expose some or all parts of their states to a custom database table using an ORM tools. To support this feature the state must implement `QueryableState`.
34+
This CorDapp demonstrates [QueryableState](https://docs.corda.net/docs/corda-os/api-persistence.html) works in Corda. Corda allows developers to have the ability to expose some or all parts of their states to a custom database table using an ORM tools. To support this feature the state must implement `QueryableState`.
3535

3636
### [Sanctionsbody -- ReferenceStates](./referenceStates-sanctionsBody):
3737
This CorDapp demonstrates the use of [reference states](https://training.corda.net/corda-details/reference-states/) in a transaction and in the verification method of a contract.
3838

39-
This CorDapp allows two nodes to enter into an IOU agreement, but enforces that both parties belong to a list of sanctioned entities. This list of sanctioned entities is taken from a referenced SanctionedEntities state.
39+
This CorDapp allows two nodes to enter into an IOU agreement, but enforces that both parties belong to a list of sanctioned entities. This list of sanctioned entities is taken from a referenced SanctionedEntities state.
4040

4141
### [Heartbeat -- SchedulableState](./schedulableState-heartbeat):
42-
This CorDapp is a simple showcase of [scheduled activities](https://docs.corda.net/docs/corda-os/event-scheduling.html#how-to-implement-scheduled-events) (i.e. activities started by a node at a specific time without direct input from the node owner).
42+
This CorDapp is a simple showcase of [scheduled activities](https://docs.corda.net/docs/corda-os/event-scheduling.html#how-to-implement-scheduled-events) (i.e. activities started by a node at a specific time without direct input from the node owner).
4343
<p align="center">
4444
<img src="./schedulableState-heartbeat/heart.jpg" alt="Corda" width="500">
4545
</p>
46+
47+
### [CustomLogging -- YoCordapp](./customlogging-yocordapp):
48+
This cordapp has some examples on how to setup custom logging with corda for either json logging and other tooling.
49+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!groovy
2+
/**
3+
* Jenkins pipeline to build the kotlin CorDapp template
4+
*/
5+
6+
/**
7+
* Kill already started job.
8+
* Assume new commit takes precedence and results from previousunfinished builds are not required.
9+
* This feature doesn't play well with disableConcurrentBuilds() option
10+
*/
11+
@Library('corda-shared-build-pipeline-steps')
12+
import static com.r3.build.BuildControl.killAllExistingBuildsForJob
13+
killAllExistingBuildsForJob(env.JOB_NAME, env.BUILD_NUMBER.toInteger())
14+
15+
pipeline {
16+
agent {
17+
label 'eight-cores'
18+
}
19+
options {
20+
ansiColor('xterm')
21+
timestamps()
22+
timeout(3*60) // 3 hours
23+
buildDiscarder(logRotator(daysToKeepStr: '7', artifactDaysToKeepStr: '7'))
24+
}
25+
stages {
26+
stage('Build') {
27+
steps {
28+
sh './gradlew --no-daemon -s clean build test deployNodes'
29+
}
30+
}
31+
}
32+
post {
33+
cleanup {
34+
deleteDir()
35+
}
36+
}
37+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Eclipse, ctags, Mac metadata, log files
2+
.classpath
3+
.project
4+
tags
5+
.DS_Store
6+
*.log
7+
*.log.gz
8+
*.orig
9+
10+
.gradle
11+
12+
# General build files
13+
**/build/*
14+
!docs/build/*
15+
16+
lib/dokka.jar
17+
18+
### JetBrains template
19+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
20+
21+
*.iml
22+
23+
## Directory-based project format:
24+
#.idea
25+
26+
# if you remove the above rule, at least ignore the following:
27+
28+
# Specific files to avoid churn
29+
.idea/*.xml
30+
.idea/copyright
31+
.idea/jsLibraryMappings.xml
32+
33+
# User-specific stuff:
34+
.idea/tasks.xml
35+
.idea/dictionaries
36+
37+
# Sensitive or high-churn files:
38+
.idea/dataSources.ids
39+
.idea/dataSources.xml
40+
.idea/sqlDataSources.xml
41+
.idea/dynamic.xml
42+
.idea/uiDesigner.xml
43+
44+
# Gradle:
45+
.idea/libraries
46+
47+
# Mongo Explorer plugin:
48+
.idea/mongoSettings.xml
49+
50+
## File-based project format:
51+
*.ipr
52+
*.iws
53+
54+
## Plugin-specific files:
55+
56+
# IntelliJ
57+
/out/
58+
workflows/out/
59+
contracts/out/
60+
clients/out/
61+
62+
# mpeltonen/sbt-idea plugin
63+
.idea_modules/
64+
65+
# JIRA plugin
66+
atlassian-ide-plugin.xml
67+
68+
# Crashlytics plugin (for Android Studio and IntelliJ)
69+
com_crashlytics_export_strings.xml
70+
crashlytics.properties
71+
crashlytics-build.properties
72+
73+
# docs related
74+
docs/virtualenv/
75+
76+
# if you use the installQuasar task
77+
lib
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2016, R3 Limited.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Logging CorDapp
2+
3+
## Custom Logging
4+
5+
This is a modified version of the original yo cordapp with some additions to use custom log4j2 configurations.
6+
7+
8+
The primary example we've implemented here is json logging which is configured in `config/dev/log4j2.xml`.
9+
10+
This gives us the ability to use Log4j thread contexts to log arbitrary objects or data points in json format.
11+
12+
In this example not only do the node logs output in json but we can add arbitrary key value pairs as well.
13+
14+
```java
15+
// here we have our first opportunity to log out the contents of the flow arguments.
16+
ThreadContext.put("initiator", me.name.toString())
17+
ThreadContext.put("target", target.name.toString())
18+
// publish to the log with the additional context
19+
logger.info("Initializing the transaction.")
20+
```
21+
22+
When we log this message, it gets output along with the other key value pairs we've specified in a JSON format:
23+
```
24+
{
25+
"instant": {
26+
"epochSecond": 1612982209,
27+
"nanoOfSecond": 487000000
28+
},
29+
"thread": "Node thread-1",
30+
"level": "INFO",
31+
"loggerName": "net.corda",
32+
"message": "Initializing the transaction.",
33+
"endOfBatch": true,
34+
"loggerFqcn": "org.apache.logging.slf4j.Log4jLogger",
35+
"contextMap": {
36+
"actor_id": "internalShell",
37+
"actor_owning_identity": "O=PartyA, L=London, C=GB",
38+
"actor_store_id": "NODE_CONFIG",
39+
"fiber-id": "10000001",
40+
"flow-id": "94543b19-b949-441e-9962-bc50dcd7ad55",
41+
"initiator": "O=PartyA, L=London, C=GB",
42+
"invocation_id": "a53a3a5d-b450-456e-a0f1-dfb7dcdce6dd",
43+
"invocation_timestamp": "2021-02-10T18:36:49.312Z",
44+
"origin": "internalShell",
45+
"session_id": "e8ba737e-e809-4a14-8c3b-284b7ae5ed88",
46+
"session_timestamp": "2021-02-10T18:36:49.022Z",
47+
"target": "O=PartyB, L=New York, C=US",
48+
"thread-id": "168"
49+
},
50+
"threadId": 168,
51+
"threadPriority": 5
52+
}
53+
```
54+
55+
56+
This can be quite powerful if you're looking to produce a consumable output stream to a log aggregator like splunk.
57+
58+
You can end up getting log feeds in json that look something like this:
59+
60+
```json
61+
{"instant":{"epochSecond":1612369055,"nanoOfSecond":12000000},"thread":"main","level":"INFO","loggerName":"net.corda.node.internal.Node","message":"Vendor: Corda Open Source","endOfBatch":true,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","threadId":1,"threadPriority":5}
62+
. . .More Node Startup loggings
63+
64+
// when our flow is run we see the log we specified
65+
{"instant":{"epochSecond":1612460471,"nanoOfSecond":866000000},"thread":"pool-10-thread-2","level":"INFO","loggerName":"net.corda.tools.shell.FlowShellCommand","message":"Executing command \"flow start net.corda.samples.logging.flows.YoFlow target: PartyA\",","endOfBatch":true,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","threadId":224,"threadPriority":5}
66+
{"instant":{"epochSecond":1612460472,"nanoOfSecond":304000000},"thread":"Node thread-1","level":"INFO","loggerName":"net.corda","message":"Initializing the transaction.","endOfBatch":true,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","threadId":166,"threadPriority":5}
67+
{"instant":{"epochSecond":1612460472,"nanoOfSecond":428000000},"thread":"pool-10-thread-2","level":"WARN","loggerName":"net.corda.tools.shell.utlities.StdoutANSIProgressRenderer","message":"Cannot find console appender - progre
68+
```
69+
70+
## Usage
71+
72+
73+
### Pre-Requisites
74+
75+
See https://docs.corda.net/getting-set-up.html.
76+
77+
78+
### Running the CorDapp
79+
80+
Open a terminal and go to the project root directory and type: (to deploy the nodes using bootstrapper)
81+
```
82+
./gradlew clean deployNodes
83+
```
84+
Then type: (to run the nodes)
85+
86+
```
87+
./build/nodes/runnodes
88+
```
89+
90+
When the nodes run you'll be able to see the node's json log files in their respesctive `logs` folders.
91+
This logging configuration will add a new file that you can view.
92+
93+
```shell
94+
tail -f build/nodes/PartyA/logs/node.json
95+
96+
{"instant":{"epochSecond":1612543764,"nanoOfSecond":930000000},"thread":"main","level":"INFO","loggerName":"net.corda.cliutils.CliWrapperBase","message":"Application Args: run-migration-scripts --core-schemas --app-schemas","endOfBatch":true,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","contextMap":{},"threadId":1,"threadPriority":5}
97+
{"instant":{"epochSecond":1612543766,"nanoOfSecond":300000000}
98+
99+
. . .
100+
```
101+
102+
### Sending a Yo
103+
104+
We will interact with the nodes via their specific shells. When the nodes are up and running, use the following command to send a
105+
Yo to another node:
106+
107+
```
108+
flow start YoFlow target: PartyB
109+
```
110+
111+
Where `NODE_NAME` is 'PartyA' or 'PartyB'. The space after the `:` is required. You are not required to use the full
112+
X500 name in the node shell. Note you can't sent a Yo! to yourself because that's not cool!
113+
114+
To see all the Yo's! other nodes have sent you in your vault (you do not store the Yo's! you send yourself), run:
115+
116+
```
117+
run vaultQuery contractStateType: YoState
118+
```
119+
120+
### Other ways to use this log configuration
121+
122+
The above method will run all nodes together but if you're running your corda node manually all you need to do is specify the particular config file.
123+
124+
You can do that by just running the jar directly:
125+
126+
```shell
127+
java -Dlog4j.configurationFile=logging-cordapp/build/resources/main/log4j2.xml -jar corda.jar
128+
```
129+
130+
> notice that all we're doing is adding this param to the command we'd otherwise use to run corda in order to specify the log file.
131+
132+
133+
## Attribution
134+
135+
This example was built with help from [Splunk](https://splunk.com), and they have our thanks.
136+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved.
2+
3+
For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at
4+
https://www.r3.com/trademark-policy/.

0 commit comments

Comments
 (0)