CloneLogger
Create and Maintain Log Tables for the CloneEngine Module
Summary:
CloneLogger was designed to capture emitted messages from CloneEngine into specified log tables. This library has functions to look for existing log tables (by name) and either create (or recreate) them, to ultimately insert (CloneEngine) output to them with minimal database hassle.
Requirements:
Quick Start:
A. Oracle Instant Client Download
B. Oracle Instant Client Installation and Configuration (this example procedure is for Mac OS X 64bit ONLY)
From a terminal window:
- Unzip your Oracle Instant Client files to
~/oracle
unzip instantclient-basic-macos.x64-12.1.0.2.0.zip -d ~/oracle
unzip instantclient-sdk-macos.x64-12.1.0.2.0.zip -d ~/oracle
- Update your .bashrc file by appending and saving the following block of code:
export OCI_HOME=~/oracle/instantclient_12_1
export OCI_LIB_DIR=$OCI_HOME
export OCI_INC_DIR=$OCI_HOME/sdk/include
export OCI_INCLUDE_DIR=$OCI_HOME/sdk/include
export DYLD_LIBRARY_PATH=$OCI_LIB_DIR
- Create the following symbolic links from within your Instant Client directory (e.g. /oracle/instantclient_12_1):
ln -s ~/oracle/instantclient_12_1/libclntsh.dylib.12.1 ~/oracle/instantclient_12_1/libclntsh.dylib
ln -s ~/oracle/instantclient_12_1/libocci.dylib.12.1 ~/oracle/instantclient_12_1/libocci.dylib
- Restart your Terminal application OR type the following
source ~/.bashrc
D. Install CloneEngine and CloneLogger
npm install cloneengine
E. Install CloneEngine and CloneLogger
npm install clonelogger
F. Run CloneEngine Operations With Clone Logger (example/template)
"use strict";
var CloneEngine = require('cloneengine');
var CloneLogger = require('clonelogger');
const SOURCE_DB = {
dbMake : 'postgres',
database : 'myPostgresDb',
user : 'me',
password : 'myPassWord',
host : 'my.db.com'
};
const DESTINATION_DB = {
dbMake : 'oracle',
database : 'myOracleDb',
user : 'me',
password : 'myPassWord',
host : 'myother.db.com',
port : 12345,
service : 'myother.db.com'
};
const OVERWRITE_FOR_ALL_OPS = 'yes';
const TIMEZONE = 'local';
const DISPLAY_MESSAGES_ON_CONSOLE = 'yes';
const RUN_TYPE = 'synchronous';
const STOP_ON_ERROR = 'yes';
const LOG_OUTPUT = 'yes';
const LOG_OUTPUT_TO = DESTINATION_DB;
const ACTIVITY_LOG = 'clone_activities';
const OPERATION_LOG = 'clone_operations';
var logger = new CloneLogger(LOG_OUTPUT_TO,
{'activityLog' : ACTIVITY_LOG,
'operationLog' : OPERATION_LOG
}
);
if (LOG_OUTPUT === 'yes'){
logger.detectActivityLog()
.then(function(response){
if(response=== false){
logger.createActivityLog();
}
})
.catch(function(err){
console.log(err);
})
logger.detectOperationLog()
.then(function(response){
if(response=== false){
logger.createOperationLog();
}
})
.catch(function(err){
console.log(err);
})
}
var handleEmitterOutput = function(msg){
if (LOG_OUTPUT === 'yes'){
logger.insert(msg)
.catch(function(err){
console.log('CloneLogger ERROR:'+err);
});
}
if (DISPLAY_MESSAGES_ON_CONSOLE === 'yes') {
if(msg.msgType === 'operation'){console.log(msg);}
else if(msg.msgType === 'ERROR!'){
console.log(
msg.activityId +' '+msg.operationId+' '+msg.step+' '+msg.operation+' \x1b[31m'+msg.msgType+'\x1b[0m'+' '+msg.time+' => '+msg.description);
}else{
console.log(
msg.activityId +' '+msg.operationId+' '+msg.step+' '+msg.operation+' '+msg.msgType+' '+msg.time+' => '+msg.description);
}
}
};
function runCloneEngineOperation (plan) {
let engine = new CloneEngine(SOURCE_DB,DESTINATION_DB,TIMEZONE);
engine.on('start',function(msg){handleEmitterOutput(msg);})
engine.on('connection',function(msg){handleEmitterOutput(msg);})
engine.on('rowsToProcess',function(msg){handleEmitterOutput(msg);})
engine.on('process',function(msg){handleEmitterOutput(msg);})
engine.on('bytesCached',function(msg){handleEmitterOutput(msg);})
engine.on('countsMatch',function(msg){handleEmitterOutput(msg);})
engine.on('finish',function(msg){handleEmitterOutput(msg);})
engine.on('ERROR!',function(msg){handleEmitterOutput(msg);})
engine.on('operation',function(msg){handleEmitterOutput(msg);})
engine.run(plan);
return new Promise(function(resolve, reject){
if (STOP_ON_ERROR === 'no') {
engine.on('ERROR!',function(msg){if (msg){resolve(msg);}})
}else{
engine.on('ERROR!',function(msg){if (msg){reject(msg);}})
}
engine.on('finish',function(msg){if (msg) {resolve(true);}})
})
};
if (RUN_TYPE === 'synchronous') {
runCloneEngineOperation({
sourceTableName : 'table_a',
destinationTableName : 'clone_a',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
.then(function(){
runCloneEngineOperation({
sourceTableName : 'table_b',
destinationTableName : 'clone_b',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
.then(function(){
runCloneEngineOperation({
sourceTableName : 'table_c',
destinationTableName : 'clone_c',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
.then(function(){
runCloneEngineOperation({
sourceTableName : 'table_d',
destinationTableName : 'clone_d',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
}).catch(function(err){console.log(err);})
}).catch(function(err){console.log(err);})
}).catch(function(err){console.log(err);});
}
if (RUN_TYPE === 'asynchronous') {
runCloneEngineOperation({
sourceTableName : 'table_a',
destinationTableName : 'clone_a',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
runCloneEngineOperation({
sourceTableName : 'table_b',
destinationTableName : 'clone_b',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
runCloneEngineOperation({
sourceTableName : 'table_c',
destinationTableName : 'clone_c',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
runCloneEngineOperation({
sourceTableName : 'table_d',
destinationTableName : 'clone_d',
overwriteDestTblIfExists : OVERWRITE_FOR_ALL_OPS
})
}