I have several Oracle databases where my in-house applications are running. Those applications use both dba_jobs
and dba_scheduler_jobs
.
I want to write monitoring function: check_my_jobs
which will be called periodically by Nagios to check if everything is OK with my jobs. (Are they running? Is it Broken? Is next_run_date delayed? and so on)
Solutions: Due to the fact that I have to monitor jobs on different databases there is two way of implementing solution:
Create a monitoring function and configuration tables only on one database which will check jobs on every database using database links.
pros: Centralized functionality, easy to maintain.
cons: I have to do the checks using database links.
Create a monitoring function and configuration tables on every database where I want to check jobs.
pros: I don't have to use DB links
cons: Duplicated monitoring code on every database
Which solution is better?
I'd go with option #1 - centralized functionality that uses database links.
Database links have an undeserved bad reputation. One of the main reasons is that too many people use public database links, where anyone connecting to the database can use the link. That's obviously a security nightmare, but it's not the default setting and it's easy to avoid that trap.
Some other issues with database links:
DBMS_UTILITY.EXEC_DDL_STATEMENT@LINK_NAME('create ...');
Make sure to only use DDL in there. Other types of commands will silently fail.Links should not be hard-coded or else they could invalidate the package. But this may not matter - you'll probably want to loop through the list of databases and use dynamic SQL anyway. And if the link doesn't exist it's pretty easy to create a new one. Here's an example:
declare
v_result varchar2(4000);
begin
--Loop through a configuration table of links.
for links in
(
select database_name, db_link
from dbs_to_monitor
left join user_db_links
on dbs_to_monitor.database_name = user_db_links.db_link
order by database_name
) loop
--Run the query if the link exists.
if links.db_link is not null then
begin
--Note the user of REPLACE and the alternative quoting mechanism, q'[...]';
--This looks a bit silly with this small example, but in a real-life query
--it avoids concatenation hell and makes the query much easier to read.
execute immediate replace(q'[
select dummy from dual@#DB_LINK#
]',
'#DB_LINK#', links.db_link)
into v_result;
dbms_output.put_line('Result: '||v_result);
--Catch errors if the links are broken or some other error happens.
exception when others then
dbms_output.put_line('Error with '||links.db_link||': '||sqlerrm);
end;
--Error if the link was not created.
--You will have to run:
--create database link LINK_NAME connect to USERNAME identified by "PASSWORD" using 'TNS_STRING';
else
dbms_output.put_line('ERROR - '||links.db_link||' does not exist!');
end if;
end loop;
end;
/
Despite all of that, database links are great because you can do everything in PL/SQL, on one database. In a single language you can create an agentless monitoring solution and don't have to worry about installing and fixing agents.
As an example, I built the open source program Method5 to do everything using database links. With that program installed you could gather results from hundreds of databases as simply as running select * from table(m5('select * from dba_jobs'));
. That program is probably overkill for your scenario but it shows that database links are all you need for a full monitoring solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With