SQL Replication Monitoring
Hi All, first post on the forums.
I'm trying to setup some monitoring of our MSSQL replication to try and keep a track and see when it fails or issues crop up.
I've tried to create a data source but am not 100% sure what i'm doing in the groovy space. I've grabbed a script that does a SQL query as a base, but i need to run a procedure (sp_replmonitorhelppublication) instead. For active discovery i'm not getting any instances.
What i have is below and would be great if anyone could poing me into the right direction as to where i've gone wrong?
In this case, mssl.MSSQLSERVER.replication_url looks like jdbc:sqlserver://server_name:1433;databasename=distribution;integratedSecurity=false;applicationIntent=ReadOnly (mainly because i didn't know how to specify the database in groovy)
import groovy.sql.Sql
// Get basic info
def hostname = hostProps.get("system.hostname")
def sqlInstances = hostProps.get("mssl.MSSQLSERVER.replication_url") ?: hostProps.get("auto.sql_server_instances") // override sql instances with manual instances
Boolean debug = false
LMDebugPrint("***** Running System Jobs AD", debug)
// This statement will return nothing if qroups aren't defined. Hard to return an error message since some named instances can be members of a group and others may not be.
def sqlQuery = """
sp_replmonitorhelppublication
"""
LMDebugPrint("\tSQL Instances ${sqlInstances}", debug)
if (sqlInstances)
{
sqlInstances.toString().tokenize(",").each
{ instanceName ->
LMDebugPrint("\tInstance Name ${instanceName}", debug)
def jdbcConnectionString = hostProps.get("mssql.${instanceName.trim()}.mssql_url") ?: hostProps.get("auto.${instanceName.trim()}.mssql_url")
def user = hostProps.get("mssql.${instanceName.trim()}.user") ?: hostProps.get("jdbc.mssql.user") ?: ""
def pass = hostProps.get("mssql.${instanceName.trim()}.pass") ?: hostProps.get("jdbc.mssql.pass") ?: ""
LMDebugPrint("\tJDBC Connection String ${jdbcConnectionString}", debug)
// ensure we dont have any null's
if (jdbcConnectionString)
{
def conn = attemptConnection(user, pass, jdbcConnectionString, debug)
if (conn.status == "success")
{
def outputRecords = runQuery(sqlQuery, conn.connection, debug)
if (outputRecords.status == 'success')
{
outputRecords.data.each { oneRecord ->
name = oneRecord.publication.toString().replaceAll(/[:|\\|\s|=]+/,"_")
publication_id = oneRecord.publication_id
publication_type = oneRecord.publication_type
retention = oneRecord.retention
instanceName = instanceName.replaceAll(/[:|\\|\s|=]+/,"_")
wildvalue = instanceName + "||" + name
// Print it out with instance level properties.
println "${wildvalue}##${name} (${instanceName})######" +
"auto.sql_instance=${instanceName}&" +
"auto.publication_name=${name}&" +
"auto.publication_id=${publication_id}&" +
"auto.publication_type=${publication_type}&" +
"auto.retention=${retention}"
}
}
}
}
}
return 0
}
else
{
return 1
}
/**
* Helper method to print out debug messages for troubleshooting purposes.
* @param message
* @param debug
* @return
*/
def LMDebugPrint(message, Boolean debug = false)
{
if (debug)
{
println(message.toString())
}
}
/**
* Helper method which handles creating a connection to the jdbc database
* @returnArray is an array with a connection, status and any error messages an array.
* *connection = jdbc connection
* *status, success or fail
* *errors, if both connection types fail there will be 2 error messages.
*
*/
def attemptConnection(String instanceUser, String instancePass, String instanceURL, Boolean debug = false)
{
LMDebugPrint("**** Props to connect:", debug)
LMDebugPrint("\tuser:$instanceUser", debug)
LMDebugPrint("\tinstanceURL:$instanceURL", debug)
def returnArray = [:]
def errors = []
def connComplete
def db_connection
try
{
// Connection creation thrown into Try/Catch block as to quickly capture any issues with initial connection.
// Create a connection to the database.
String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
db_connection = Sql.newInstance(instanceURL, instanceUser, instancePass, driver)
connComplete = true
}
catch (Exception e)
{
// Print out the exception and exit with 1.
errors[0] = e.message
LMDebugPrint("***** Attempt Connection error: ${e.message}", debug)
connComplete = false
}
// populate the connection and any messages for the return array
if (connComplete == true)
{
returnArray['connection'] = db_connection
returnArray['status'] = 'success'
}
else
{
returnArray['status'] = 'failed'
returnArray['errors'] = errors
returnArray['connection'] = null
}
return returnArray
}
/*
Attempt to execute SQL command.
Returns an array.
the first element is the query data
second element is success or fail
third element is the error message
*/
def runQuery(String sqlQuery, conn, debug = false)
{
def returnArray = [:]
LMDebugPrint("****Running Query****", debug)
LMDebugPrint("\tQuery to run: $sqlQuery", debug)
// query the Oracle DB.
try
{
returnArray['data'] = conn.rows(sqlQuery)
returnArray['status'] = 'success'
returnArray['error'] = ''
}
catch (Exception e)
{
returnArray['error'] = e.message
returnArray['status'] = 'failed'
LMDebugPrint("\tSQL Query Error message: ${e.message}", debug)
}
LMDebugPrint("Data Returned: ${returnArray.data}", debug)
return returnArray
}