Browse Source

Merge branch 'feature/add-logging' into 'develop'

Feature/add logging

See merge request ecentrics/concordia!18
develop
Apostolos Fanakis 4 years ago
parent
commit
19dbbb4f0c
  1. 12
      docker/Makefile
  2. 1
      docker/env/contracts-provider.env
  3. 1
      docker/env/pinner.env
  4. 4
      packages/concordia-app/.eslintrc.js
  5. 2
      packages/concordia-app/src/components/ClearDatabasesModal/index.jsx
  6. 2
      packages/concordia-app/src/components/PostCreate/index.jsx
  7. 2
      packages/concordia-app/src/views/Profile/GeneralTab/EditInformationModal/index.jsx
  8. 2
      packages/concordia-app/src/views/Register/PersonalInformationStep/index.jsx
  9. 2
      packages/concordia-app/src/views/Topic/TopicCreate/index.jsx
  10. 1
      packages/concordia-contracts-provider/.gitignore
  11. 4
      packages/concordia-contracts-provider/package.json
  12. 2
      packages/concordia-contracts-provider/src/constants.js
  13. 7
      packages/concordia-contracts-provider/src/controllers/download.js
  14. 13
      packages/concordia-contracts-provider/src/controllers/upload.js
  15. 12
      packages/concordia-contracts-provider/src/index.js
  16. 9
      packages/concordia-contracts-provider/src/utils/logger.js
  17. 1
      packages/concordia-pinner/.gitignore
  18. 2
      packages/concordia-pinner/package.json
  19. 18
      packages/concordia-pinner/src/app.js
  20. 5
      packages/concordia-pinner/src/constants.js
  21. 15
      packages/concordia-pinner/src/index.js
  22. 5
      packages/concordia-pinner/src/options/ipfsOptions.js
  23. 17
      packages/concordia-pinner/src/utils/drizzleUtils.js
  24. 3
      packages/concordia-pinner/src/utils/ipfsUtils.js
  25. 9
      packages/concordia-pinner/src/utils/logger.js
  26. 7
      packages/concordia-pinner/src/utils/orbitUtils.js
  27. 48
      packages/concordia-shared/src/logging/node/winstonLogUtils.js
  28. 1765
      yarn.lock

12
docker/Makefile

@ -72,21 +72,21 @@ run-app-host-chain:
build-contracts-provider: build-contracts-provider:
@docker build ../ -f ./concordia-contracts-provider/Dockerfile -t ecentrics/concordia-contracts-provider --build-arg TZ=Europe/Athens @docker build ../ -f ./concordia-contracts-provider/Dockerfile -t ecentrics/concordia-contracts-provider --build-arg TZ=Europe/Athens
run-contracts-provider-staging: run-contracts-provider-staging:
@docker run -d -v ${CONTRACTS_PROVIDER_VOLUMES}/contracts:/mnt/concordia/contracts --env-file=./env/contracts-provider.env -p 8400:8400 --name concordia-contracts-provider --net=concordia_concordia_network ecentrics/concordia-contracts-provider:latest @docker run -d -v ${CONTRACTS_PROVIDER_VOLUMES}/contracts:/mnt/concordia/contracts -v ${CONTRACTS_PROVIDER_VOLUMES}/contracts:/mnt/concordia/logs --env-file=./env/contracts-provider.env -p 8400:8400 --name concordia-contracts-provider --net=concordia_concordia_network ecentrics/concordia-contracts-provider:latest
run-contracts-provider: run-contracts-provider:
@docker run -d -v ${CONTRACTS_PROVIDER_VOLUMES}/contracts:/mnt/concordia/contracts --env-file=./env/contracts-provider.env -e NODE_ENV=production -p 8400:8400 --name concordia-contracts-provider --net=concordia_concordia_network ecentrics/concordia-contracts-provider:latest @docker run -d -v ${CONTRACTS_PROVIDER_VOLUMES}/contracts:/mnt/concordia/contracts -v ${CONTRACTS_PROVIDER_VOLUMES}/contracts:/mnt/concordia/logs --env-file=./env/contracts-provider.env -e NODE_ENV=production -p 8400:8400 --name concordia-contracts-provider --net=concordia_concordia_network ecentrics/concordia-contracts-provider:latest
# Pinner targets # Pinner targets
build-pinner: build-pinner:
@docker build ../ -f ./concordia-pinner/Dockerfile -t ecentrics/concordia-pinner --build-arg TZ=Europe/Athens @docker build ../ -f ./concordia-pinner/Dockerfile -t ecentrics/concordia-pinner --build-arg TZ=Europe/Athens
run-pinner-staging: run-pinner-staging:
@docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb --env-file=./env/pinner.env -p 4444:4444 --name concordia-pinner --net=concordia_concordia_network ecentrics/concordia-pinner:latest @docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb -v ${PINNER_VOLUMES}:/mnt/concordia/logs --env-file=./env/pinner.env -p 4444:4444 --name concordia-pinner --net=concordia_concordia_network ecentrics/concordia-pinner:latest
run-pinner: run-pinner:
@docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb --env-file=./env/pinner.env -e NODE_ENV=production -p 4444:4444 --name concordia-pinner --net=concordia_concordia_network ecentrics/concordia-pinner:latest @docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb -v ${PINNER_VOLUMES}:/mnt/concordia/logs --env-file=./env/pinner.env -e NODE_ENV=production -p 4444:4444 --name concordia-pinner --net=concordia_concordia_network ecentrics/concordia-pinner:latest
run-pinner-staging-host: run-pinner-staging-host:
@docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb --env-file=./env/pinner.env --net=host --name concordia-pinner ecentrics/concordia-pinner:latest @docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb -v ${PINNER_VOLUMES}:/mnt/concordia/logs --env-file=./env/pinner.env --net=host --name concordia-pinner ecentrics/concordia-pinner:latest
run-pinner-host: run-pinner-host:
@docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb --env-file=./env/pinner.env -e NODE_ENV=production --net=host --name concordia-pinner ecentrics/concordia-pinner:latest @docker run -d -v ${PINNER_VOLUMES}/orbitdb:/mnt/concordia/orbitdb -v ${PINNER_VOLUMES}:/mnt/concordia/logs --env-file=./env/pinner.env -e NODE_ENV=production --net=host --name concordia-pinner ecentrics/concordia-pinner:latest
# Other # Other
clean-images: clean-images:

1
docker/env/contracts-provider.env

@ -1 +1,2 @@
UPLOAD_CONTRACTS_DIRECTORY=/mnt/concordia/contracts/ UPLOAD_CONTRACTS_DIRECTORY=/mnt/concordia/contracts/
LOGS_PATH=/mnt/concordia/logs/

1
docker/env/pinner.env

@ -1,5 +1,6 @@
USE_EXTERNAL_CONTRACTS_PROVIDER=true USE_EXTERNAL_CONTRACTS_PROVIDER=true
ORBIT_DIRECTORY=/mnt/concordia/orbitdb ORBIT_DIRECTORY=/mnt/concordia/orbitdb
LOGS_PATH=/mnt/concordia/logs/
CONTRACTS_PROVIDER_HOST=concordia-contracts-provider CONTRACTS_PROVIDER_HOST=concordia-contracts-provider
CONTRACTS_PROVIDER_PORT=8400 CONTRACTS_PROVIDER_PORT=8400

4
packages/concordia-app/.eslintrc.js

@ -41,10 +41,10 @@ module.exports = {
'react-hooks/exhaustive-deps': 'error', 'react-hooks/exhaustive-deps': 'error',
'max-len': ['warn', {'code': 120, 'tabWidth': 4}], 'max-len': ['warn', {'code': 120, 'tabWidth': 4}],
'no-unused-vars': 'warn', 'no-unused-vars': 'warn',
'no-console': 'warn', 'no-console': ['warn', {allow: ['warn', 'error']}],
'no-shadow': 'warn', 'no-shadow': 'warn',
"no-multi-str": "warn", "no-multi-str": "warn",
"jsx-a11y/label-has-associated-control": [ 2, { "jsx-a11y/label-has-associated-control": [2, {
"labelAttributes": ["label"], "labelAttributes": ["label"],
"controlComponents": ["Input"], "controlComponents": ["Input"],
"depth": 3, "depth": 3,

2
packages/concordia-app/src/components/ClearDatabasesModal/index.jsx

@ -36,7 +36,7 @@ const ClearDatabasesModal = (props) => {
purgeIndexedDBs() purgeIndexedDBs()
.then(() => { .then(() => {
onDatabasesCleared(); onDatabasesCleared();
}).catch((reason) => console.log(reason)); }).catch((reason) => console.error(reason));
}, [onDatabasesCleared]); }, [onDatabasesCleared]);
const onCancelTry = useCallback(() => { const onCancelTry = useCallback(() => {

2
packages/concordia-app/src/components/PostCreate/index.jsx

@ -95,7 +95,7 @@ const PostCreate = (props) => {
setCreatePostCacheSendStackId(''); setCreatePostCacheSendStackId('');
}) })
.catch((reason) => { .catch((reason) => {
console.log(reason); console.error(reason);
}); });
setStoringPost(true); setStoringPost(true);

2
packages/concordia-app/src/views/Profile/GeneralTab/EditInformationModal/index.jsx

@ -124,7 +124,7 @@ const EditInformationModal = (props) => {
// TODO: display a message // TODO: display a message
}) })
.catch((reason) => { .catch((reason) => {
console.log(reason); console.error(reason);
}); });
if (usernameInput !== initialUsername) { if (usernameInput !== initialUsername) {

2
packages/concordia-app/src/views/Register/PersonalInformationStep/index.jsx

@ -94,7 +94,7 @@ const PersonalInformationStep = (props) => {
Promise.resolve()) Promise.resolve())
.then(() => pushNextStep()) .then(() => pushNextStep())
.catch((reason) => { .catch((reason) => {
console.log(reason); console.error(reason);
}); });
} }
}, [error, locationInput, profilePictureInput, pushNextStep]); }, [error, locationInput, profilePictureInput, pushNextStep]);

2
packages/concordia-app/src/views/Topic/TopicCreate/index.jsx

@ -80,7 +80,7 @@ const TopicCreate = (props) => {
history.push(`/topics/${topicId}`); history.push(`/topics/${topicId}`);
}) })
.catch((reason) => { .catch((reason) => {
console.log(reason); console.error(reason);
}); });
} }
} }

1
packages/concordia-contracts-provider/.gitignore

@ -11,6 +11,7 @@
# Logs # Logs
/log /log
/logs
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*

4
packages/concordia-contracts-provider/package.json

@ -17,8 +17,10 @@
"express-async-handler": "^1.1.4", "express-async-handler": "^1.1.4",
"helmet": "^4.4.1", "helmet": "^4.4.1",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"morgan": "^1.10.0",
"multer": "^1.4.2", "multer": "^1.4.2",
"multiparty": "^4.2.2" "multiparty": "^4.2.2",
"winston": "^3.3.3"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^7.19.0", "eslint": "^7.19.0",

2
packages/concordia-contracts-provider/src/constants.js

@ -2,8 +2,10 @@ import path from 'path';
const UPLOAD_CONTRACTS_DIRECTORY = path.join(__dirname, '..', 'contracts-uploads'); const UPLOAD_CONTRACTS_DIRECTORY = path.join(__dirname, '..', 'contracts-uploads');
const CORS_ALLOWED_ORIGINS = ['http://127.0.0.1:7000', 'http://localhost:7000']; const CORS_ALLOWED_ORIGINS = ['http://127.0.0.1:7000', 'http://localhost:7000'];
const LOGS_PATH = path.join(__dirname, '..', 'logs');
export default { export default {
uploadsDirectory: UPLOAD_CONTRACTS_DIRECTORY, uploadsDirectory: UPLOAD_CONTRACTS_DIRECTORY,
corsAllowedOrigins: CORS_ALLOWED_ORIGINS, corsAllowedOrigins: CORS_ALLOWED_ORIGINS,
logsPath: LOGS_PATH,
}; };

7
packages/concordia-contracts-provider/src/controllers/download.js

@ -1,6 +1,7 @@
import { promises as fs, constants } from 'fs'; import { promises as fs, constants } from 'fs';
import path from 'path'; import path from 'path';
import { getStorageLocation, getTagsDirectory } from '../utils/storageUtils'; import { getStorageLocation, getTagsDirectory } from '../utils/storageUtils';
import { logger } from '../utils/logger';
const readContractFilesToArray = (contractsDirectoryPath) => fs const readContractFilesToArray = (contractsDirectoryPath) => fs
.readdir(contractsDirectoryPath) .readdir(contractsDirectoryPath)
@ -8,7 +9,11 @@ const readContractFilesToArray = (contractsDirectoryPath) => fs
.map((contractFilename) => fs .map((contractFilename) => fs
.readFile(path.join(`${contractsDirectoryPath}/${contractFilename}`), 'utf-8') .readFile(path.join(`${contractsDirectoryPath}/${contractFilename}`), 'utf-8')
.then((rawContractData) => JSON.parse(rawContractData)))) .then((rawContractData) => JSON.parse(rawContractData))))
.then((contractObjectPromises) => Promise.all([...contractObjectPromises])); .then((contractObjectPromises) => Promise.all([...contractObjectPromises]))
.then((contracts) => {
logger.info(`Successfully read ${contracts.length} contract(s) from dir: ${contractsDirectoryPath}`);
return contracts;
});
const downloadContracts = async (req, res) => { const downloadContracts = async (req, res) => {
const { params: { hash: identifier } } = req; const { params: { hash: identifier } } = req;

13
packages/concordia-contracts-provider/src/controllers/upload.js

@ -2,6 +2,7 @@ import path from 'path';
import { constants, promises as fs } from 'fs'; import { constants, promises as fs } from 'fs';
import uploadFilesUsingMiddleware from '../middleware/upload'; import uploadFilesUsingMiddleware from '../middleware/upload';
import { getStorageLocation, getTagsDirectory } from '../utils/storageUtils'; import { getStorageLocation, getTagsDirectory } from '../utils/storageUtils';
import { logger } from '../utils/logger';
const provisionContractsDirectory = (req) => { const provisionContractsDirectory = (req) => {
const { params: { hash } } = req; const { params: { hash } } = req;
@ -11,7 +12,11 @@ const provisionContractsDirectory = (req) => {
.access(contractsPath, constants.W_OK) .access(contractsPath, constants.W_OK)
.then(() => fs.rmdir(contractsPath, { recursive: true })) .then(() => fs.rmdir(contractsPath, { recursive: true }))
.catch(() => Promise.resolve()) .catch(() => Promise.resolve())
.then(() => fs.mkdir(contractsPath, { recursive: true })); .then(() => fs.mkdir(contractsPath, { recursive: true }))
.then((ignored) => {
logger.info(`Provisioned new contracts directory: ${contractsPath}`);
return ignored;
});
}; };
const addOrTransferTag = (tag, hash) => { const addOrTransferTag = (tag, hash) => {
@ -20,7 +25,11 @@ const addOrTransferTag = (tag, hash) => {
return fs return fs
.mkdir(tagsDirectory, { recursive: true }) .mkdir(tagsDirectory, { recursive: true })
.then(() => fs.writeFile(tagFilePath, hash, 'utf-8')); .then(() => fs.writeFile(tagFilePath, hash, 'utf-8'))
.then((ignored) => {
logger.info(`Tag modified: ${tag} -> ${hash}`);
return ignored;
});
}; };
const uploadContracts = async (req, res) => provisionContractsDirectory(req) const uploadContracts = async (req, res) => provisionContractsDirectory(req)

12
packages/concordia-contracts-provider/src/index.js

@ -1,14 +1,23 @@
import express from 'express'; import express from 'express';
import morgan from 'morgan';
import cors from 'cors'; import cors from 'cors';
import helmet from 'helmet'; import helmet from 'helmet';
import { contractsProviderPort } from 'concordia-shared/src/environment/interpolated/contractsProvider'; import { contractsProviderPort } from 'concordia-shared/src/environment/interpolated/contractsProvider';
import fs from 'fs';
import path from 'path';
import initRoutes from './routes/web'; import initRoutes from './routes/web';
import constants from './constants'; import constants from './constants';
import { logger, logsDirectoryPath } from './utils/logger';
const accessLogStream = fs.createWriteStream(path.join(logsDirectoryPath, 'access.log'), { flags: 'a' });
logger.info('Service setting up.');
const ALLOWED_ORIGINS = process.env.CORS_ALLOWED_ORIGINS const ALLOWED_ORIGINS = process.env.CORS_ALLOWED_ORIGINS
? process.env.CORS_ALLOWED_ORIGINS.split(';') ? process.env.CORS_ALLOWED_ORIGINS.split(';')
: constants.corsAllowedOrigins; : constants.corsAllowedOrigins;
logger.info(`Allowed origins: ${ALLOWED_ORIGINS.join(', ')}`);
const app = express(); const app = express();
const corsOptions = { const corsOptions = {
@ -19,9 +28,10 @@ const corsOptions = {
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
app.use(cors(corsOptions)); app.use(cors(corsOptions));
app.use(helmet()); app.use(helmet());
app.use(morgan('combined', { stream: accessLogStream }));
initRoutes(app); initRoutes(app);
app.listen(contractsProviderPort, () => { app.listen(contractsProviderPort, () => {
console.log(`Contracts provider listening at http://127.0.0.1:${contractsProviderPort}`); logger.info(`Contracts provider listening at http://127.0.0.1:${contractsProviderPort}`);
}); });

9
packages/concordia-contracts-provider/src/utils/logger.js

@ -0,0 +1,9 @@
import winston from 'winston';
import fs from 'fs';
import getLogger from 'concordia-shared/src/logging/node/winstonLogUtils';
import constants from '../constants';
export const logsDirectoryPath = process.env.LOGS_PATH || constants.logsPath;
fs.mkdirSync(logsDirectoryPath, { recursive: true });
export const logger = getLogger(winston, logsDirectoryPath, 'concordia-contracts-provider');

1
packages/concordia-pinner/.gitignore

@ -15,6 +15,7 @@ packages/concordia-contracts/build
# Logs # Logs
/log /log
/logs
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*

2
packages/concordia-pinner/package.json

@ -29,12 +29,14 @@
"libp2p-tcp": "~0.15.1", "libp2p-tcp": "~0.15.1",
"libp2p-webrtc-star": "~0.21.1", "libp2p-webrtc-star": "~0.21.1",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"morgan": "^1.10.0",
"orbit-db": "~0.26.0", "orbit-db": "~0.26.0",
"orbit-db-identity-provider": "~0.3.1", "orbit-db-identity-provider": "~0.3.1",
"rimraf": "~3.0.2", "rimraf": "~3.0.2",
"unirest": "^0.6.0", "unirest": "^0.6.0",
"web3": "~1.3.0", "web3": "~1.3.0",
"web3-eth-contract": "^1.3.1", "web3-eth-contract": "^1.3.1",
"winston": "^3.3.3",
"wrtc": "~0.4.6" "wrtc": "~0.4.6"
} }
} }

18
packages/concordia-pinner/src/app.js

@ -1,11 +1,17 @@
import express from 'express'; import express from 'express';
import morgan from 'morgan';
import _ from 'lodash'; import _ from 'lodash';
import fs from 'fs';
import path from 'path';
import isReachable from 'is-reachable'; import isReachable from 'is-reachable';
import { pinnerApiPort } from 'concordia-shared/src/environment/interpolated/pinner'; import { pinnerApiPort } from 'concordia-shared/src/environment/interpolated/pinner';
import getWeb3ProviderUrl from 'concordia-shared/src/utils/web3'; import getWeb3ProviderUrl from 'concordia-shared/src/utils/web3';
import { getResolvedRendezvousUrl } from './utils/ipfsUtils'; import { getResolvedRendezvousUrl } from './utils/ipfsUtils';
import { logger, logsDirectoryPath } from './utils/logger';
const POLLING_INTERVAL = 1000; const POLLING_INTERVAL = 1000;
const accessLogStream = fs.createWriteStream(path.join(logsDirectoryPath, 'access.log'), { flags: 'a' });
logger.info('Service setting up.');
const responseBody = { const responseBody = {
ipfs: { ipfs: {
@ -18,11 +24,12 @@ const responseBody = {
}; };
getResolvedRendezvousUrl().then(({ address }) => { getResolvedRendezvousUrl().then(({ address }) => {
logger.info(`Resolved rendezvous URL to: ${address}`);
responseBody.rendezvous.url = address; responseBody.rendezvous.url = address;
}); });
const getStats = async (orbit) => { const getStats = async (orbit) => {
const { address: resolvedRendezvousUrl } = await getResolvedRendezvousUrl(); logger.info('Gathering stats.');
try { try {
const ipfs = orbit._ipfs; const ipfs = orbit._ipfs;
@ -34,7 +41,7 @@ const getStats = async (orbit) => {
const orbitIdentity = orbit.identity; const orbitIdentity = orbit.identity;
const databases = Object.keys(orbit.stores); const databases = Object.keys(orbit.stores);
const isWeb3Reachable = await isReachable(getWeb3ProviderUrl()); const isWeb3Reachable = await isReachable(getWeb3ProviderUrl());
const isRendezvousReachable = await isReachable(resolvedRendezvousUrl.address); const isRendezvousReachable = responseBody.rendezvous.url ? await isReachable(responseBody.rendezvous.url) : false;
const timestamp = +new Date(); const timestamp = +new Date();
responseBody.ipfs.id = id; responseBody.ipfs.id = id;
@ -48,18 +55,21 @@ const getStats = async (orbit) => {
responseBody.rendezvous.reachable = isRendezvousReachable; responseBody.rendezvous.reachable = isRendezvousReachable;
responseBody.timestamp = timestamp; responseBody.timestamp = timestamp;
} catch (err) { } catch (err) {
console.error('Error while getting stats:', err); logger.error('Error while getting stats:', err);
} }
}; };
const startAPI = (orbit) => { const startAPI = (orbit) => {
const app = express(); const app = express();
app.use(morgan('combined', { stream: accessLogStream }));
app.get('/', async (req, res) => { app.get('/', async (req, res) => {
res.send(responseBody); res.send(responseBody);
}); });
app.listen(pinnerApiPort, () => { app.listen(pinnerApiPort, () => {
console.log(`Pinner API at http://localhost:${pinnerApiPort}!`); logger.info(`Pinner API at http://localhost:${pinnerApiPort}!`);
}); });
setInterval(getStats, POLLING_INTERVAL, orbit); setInterval(getStats, POLLING_INTERVAL, orbit);

5
packages/concordia-pinner/src/constants.js

@ -1,5 +1,4 @@
import path from 'path'; import path from 'path';
const ORBIT_DIRECTORY_DEFAULT = path.join(__dirname, '..', 'orbitdb'); export const ORBIT_DIRECTORY_DEFAULT = path.join(__dirname, '..', 'orbitdb');
export const LOGS_PATH = path.join(__dirname, '..', 'logs');
export default ORBIT_DIRECTORY_DEFAULT;

15
packages/concordia-pinner/src/index.js

@ -8,16 +8,17 @@ import { createOrbitInstance, getPeerDatabases, openKVDBs } from './utils/orbitU
import startAPI from './app'; import startAPI from './app';
import downloadContractArtifacts from './utils/drizzleUtils'; import downloadContractArtifacts from './utils/drizzleUtils';
import getIpfsOptions from './options/ipfsOptions'; import getIpfsOptions from './options/ipfsOptions';
import { logger } from './utils/logger';
process.on('unhandledRejection', (error) => { process.on('unhandledRejection', (error) => {
// This happens when attempting to initialize without any available Swarm addresses (e.g. Rendezvous) // This happens when attempting to initialize without any available Swarm addresses (e.g. Rendezvous)
if (error.code === 'ERR_NO_VALID_ADDRESSES') { if (error.code === 'ERR_NO_VALID_ADDRESSES') {
console.error('unhandledRejection', error.message); logger.error(`unhandledRejection: ${error.message}`);
process.exit(1); process.exit(1);
} }
// Don't swallow other errors // Don't swallow other errors
console.error(error); logger.error(error);
throw error; throw error;
}); });
@ -25,7 +26,6 @@ const getDeployedContract = async (web3) => {
let forumContractPromise; let forumContractPromise;
if (process.env.USE_EXTERNAL_CONTRACTS_PROVIDER) { if (process.env.USE_EXTERNAL_CONTRACTS_PROVIDER) {
console.log('Downloading contracts.');
forumContractPromise = downloadContractArtifacts() forumContractPromise = downloadContractArtifacts()
.then((remoteContracts) => remoteContracts .then((remoteContracts) => remoteContracts
.find((remoteContract) => remoteContract.contractName === FORUM_CONTRACT)); .find((remoteContract) => remoteContract.contractName === FORUM_CONTRACT));
@ -57,14 +57,15 @@ const handleWeb3LogEvent = (web3, eventJsonInterface, orbit) => (error, result)
result.topics.slice(1), result.topics.slice(1),
); );
const userAddress = eventObj[1]; const userAddress = eventObj[1];
console.log('User signed up:', userAddress);
logger.info(`User signed up: ${userAddress}`);
getPeerDatabases(orbit, [userAddress]) getPeerDatabases(orbit, [userAddress])
.then((peerDBs) => openKVDBs(orbit, peerDBs)); .then((peerDBs) => openKVDBs(orbit, peerDBs));
} }
}; };
const main = async () => { const main = async () => {
console.log('Initializing...'); logger.info('Initializing IPFS and orbitDb.');
const web3 = new Web3(new Web3.providers.WebsocketProvider(getWeb3ProviderUrl())); const web3 = new Web3(new Web3.providers.WebsocketProvider(getWeb3ProviderUrl()));
getDeployedContract(web3) getDeployedContract(web3)
@ -87,11 +88,11 @@ const main = async () => {
orbit._ipfs.libp2p.connectionManager.on( orbit._ipfs.libp2p.connectionManager.on(
'peer:connect', 'peer:connect',
(peerInfo) => console.log('Peer connected: ', peerInfo.remotePeer.toB58String()), (peerInfo) => logger.info(`Peer connected: ${peerInfo.remotePeer.toB58String()}`),
); );
orbit._ipfs.libp2p.connectionManager.on( orbit._ipfs.libp2p.connectionManager.on(
'peer:disconnect', 'peer:disconnect',
(peerInfo) => console.log('Peer disconnected: ', peerInfo.remotePeer.toB58String()), (peerInfo) => logger.info(`Peer disconnected: ${peerInfo.remotePeer.toB58String()}`),
); );
startAPI(orbit); startAPI(orbit);
}))); })));

5
packages/concordia-pinner/src/options/ipfsOptions.js

@ -1,7 +1,12 @@
import getLibp2pBundle from './libp2pBundle'; import getLibp2pBundle from './libp2pBundle';
import { getSwarmAddresses } from '../utils/ipfsUtils'; import { getSwarmAddresses } from '../utils/ipfsUtils';
import { logger } from '../utils/logger';
const getIpfsOptions = async () => getSwarmAddresses() const getIpfsOptions = async () => getSwarmAddresses()
.then((swarmAddresses) => {
logger.info(`Swarm addresses used: ${swarmAddresses.join(', ')}`);
return swarmAddresses;
})
.then((swarmAddresses) => ({ .then((swarmAddresses) => ({
repo: 'ipfs', repo: 'ipfs',
config: { config: {

17
packages/concordia-pinner/src/utils/drizzleUtils.js

@ -6,29 +6,42 @@ import {
} from 'concordia-shared/src/environment/interpolated/contractsProvider'; } from 'concordia-shared/src/environment/interpolated/contractsProvider';
import { pinnerApiHost, pinnerApiPort } from 'concordia-shared/src/environment/interpolated/pinner'; import { pinnerApiHost, pinnerApiPort } from 'concordia-shared/src/environment/interpolated/pinner';
import { FORUM_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames'; import { FORUM_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames';
import { logger } from './logger';
function getContractsDownloadRequest() { function getContractsDownloadRequest() {
const HOST = pinnerApiHost; const HOST = pinnerApiHost;
const PORT = pinnerApiPort; const PORT = pinnerApiPort;
const contractsProviderAddress = `http://${contractsProviderHost}:${contractsProviderPort}/contracts/\
${contractsVersionHash}`;
const selfAddress = `${HOST}:${PORT}`;
logger.info(`Trying contracts provider address: ${contractsProviderAddress}`);
logger.info(`Sending with CORS address: ${selfAddress}`);
return unirest( return unirest(
'GET', 'GET',
`http://${contractsProviderHost}:${contractsProviderPort}/contracts/${contractsVersionHash}`, contractsProviderAddress,
).headers({ ).headers({
'Access-Control-Allow-Origin': `${HOST}:${PORT}`, 'Access-Control-Allow-Origin': selfAddress,
'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Credentials': 'true',
}); });
} }
const validateRemoteContracts = (remoteContracts) => { const validateRemoteContracts = (remoteContracts) => {
logger.info('Validating remote contracts.');
if (!remoteContracts if (!remoteContracts
.map((remoteContract) => remoteContract.contractName) .map((remoteContract) => remoteContract.contractName)
.includes(FORUM_CONTRACT)) { .includes(FORUM_CONTRACT)) {
throw new Error('Forum contract is missing from artifacts.'); throw new Error('Forum contract is missing from artifacts.');
} }
logger.info('Remote contracts valid.');
}; };
const downloadContractArtifacts = () => { const downloadContractArtifacts = () => {
logger.info('Downloading contracts.');
const request = getContractsDownloadRequest(); const request = getContractsDownloadRequest();
return new Promise((resolve, reject) => request return new Promise((resolve, reject) => request

3
packages/concordia-pinner/src/utils/ipfsUtils.js

@ -1,11 +1,12 @@
import dns from 'dns'; import dns from 'dns';
import util from 'util'; import util from 'util';
import { rendezvousHost, rendezvousPort } from 'concordia-shared/src/environment/interpolated/rendezvous'; import { rendezvousHost, rendezvousPort } from 'concordia-shared/src/environment/interpolated/rendezvous';
import { logger } from './logger';
const dnsLookup = util.promisify(dns.lookup); const dnsLookup = util.promisify(dns.lookup);
export const getResolvedRendezvousUrl = async () => dnsLookup(rendezvousHost, { family: 4 }) export const getResolvedRendezvousUrl = async () => dnsLookup(rendezvousHost, { family: 4 })
.catch((error) => console.error(new Error(`DNS lookup of ${rendezvousHost} failed.\n${error}`))); .catch((error) => logger.error(new Error(`DNS lookup of ${rendezvousHost} failed.\n${error}`)));
export const getSwarmAddresses = async () => getResolvedRendezvousUrl() export const getSwarmAddresses = async () => getResolvedRendezvousUrl()
.then((resolvedRendezvousUrl) => [`/ip4/${resolvedRendezvousUrl.address}/tcp/${rendezvousPort}/wss/p2p-webrtc-star`]); .then((resolvedRendezvousUrl) => [`/ip4/${resolvedRendezvousUrl.address}/tcp/${rendezvousPort}/wss/p2p-webrtc-star`]);

9
packages/concordia-pinner/src/utils/logger.js

@ -0,0 +1,9 @@
import winston from 'winston';
import fs from 'fs';
import getLogger from 'concordia-shared/src/logging/node/winstonLogUtils';
import { LOGS_PATH } from '../constants';
export const logsDirectoryPath = process.env.LOGS_PATH || LOGS_PATH;
fs.mkdirSync(logsDirectoryPath, { recursive: true });
export const logger = getLogger(winston, logsDirectoryPath, 'concordia-pinner');

7
packages/concordia-pinner/src/utils/orbitUtils.js

@ -2,7 +2,8 @@ import OrbitDB from 'orbit-db';
import Identities from 'orbit-db-identity-provider'; import Identities from 'orbit-db-identity-provider';
import { EthereumContractIdentityProvider } from '@ezerous/eth-identity-provider'; import { EthereumContractIdentityProvider } from '@ezerous/eth-identity-provider';
import Web3 from 'web3'; import Web3 from 'web3';
import ORBIT_DIRECTORY_DEFAULT from '../constants'; import { ORBIT_DIRECTORY_DEFAULT } from '../constants';
import { logger } from './logger';
// TODO: share code below with frontend (?) // TODO: share code below with frontend (?)
const determineDBAddress = async ({ const determineDBAddress = async ({
@ -40,7 +41,7 @@ export const openKVDBs = async (orbit, databases) => {
.forEach((database) => { .forEach((database) => {
orbit orbit
.keyvalue(database) .keyvalue(database)
.then((store) => store.events.on('replicated', (address) => console.log(`Replicated ${address}`))); .then((store) => store.events.on('replicated', (address) => logger.info(`Replicated ${address}`)));
console.log(`Opened ${database}`); logger.info(`Opened ${database}`);
}); });
}; };

48
packages/concordia-shared/src/logging/node/winstonLogUtils.js

@ -0,0 +1,48 @@
const path = require('path');
const getLogger = (winston, logsDirectory, serviceName) => {
const transports = [
new winston.transports.File({
filename: path.join(logsDirectory, 'error.log'),
level: 'error',
}),
new winston.transports.File({
filename: path.join(logsDirectory, 'combined.log'),
}),
];
const exceptionHandlers = [
new winston.transports.File({ filename: path.join(logsDirectory, 'exceptions.log') }),
];
if (process.env.NODE_ENV !== 'production') {
transports.push(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
winston.format.simple(),
),
}));
exceptionHandlers.push(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
winston.format.simple(),
),
}));
}
return winston.createLogger({
level: process.env.NODE_ENV === 'production' ? 'info' : 'silly',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json(),
),
defaultMeta: { service: serviceName },
transports,
exceptionHandlers,
});
};
module.exports = getLogger;

1765
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save