วันอังคารที่ 7 มกราคม พ.ศ. 2557

Cacti + ORACLE ตอนที่ 1: สร้างสคริปท์ PHP เพื่ออ่านค่าจากฐานข้อมูล

ในกาีรทำงานของ Cacti ที่จะสร้าง poller ไปทำการ query ข้อมูลจากระบบที่ต้องการนั้นจะใช้การทำงานจาก SNMP โปรโตคอลเป็นหลัก แต่ในบางกรณีที่เป็นการ query ข้อมูลที่มีลักษณะพิเศษหรือเป็นการทำงานเฉพาะกิจบางอย่างนั้น จะไม่ได้มี SNMP มาให้ เราจึงต้องใช้วิธีการอื่นเพื่อใช้ query ข้อมูลออกมา

สำหรับ ORACLE Database ที่เราจะทำกันในบทนี้เราจะใช้วิธีที่เรียกว่า Data Input Methods ที่มีให้เลือกใช้ในเมนูของ Cacti ดังรูป


ในตัวอย่างนี้ผมจะสร้าง Data Input Methods ใหม่ขึ้นมาตั้งชื่อว่า Oracle Monitor Query เป็นฟังชั่นที่เราจะนำมาใช้สำหรับการ connect ไปยังระบบฐานข้อมูล ORACLE โดยฟังชั่นที่เราสร้างขึ้นมานี้ จะสามารถรับ input เพื่อนำไปประมวลผลค่าออกมาได้ ดังนั้นเราจะสร้างแค่ครั้งเีดียวแล้วจะประยุกต์ใช้ในการทำงานกับแต่ะละ SQL ที่เราจะนำไป query ได้จากหลายๆระบบ

Input Type กำหนดเป็น Script - Script Server (PHP) เพราะเราจะใช้การเรียก php สคริปท์จาก command line เพื่อติดต่อไปยังฐานข้อมูล ORACLE โดยใน php.ini เราจะต้องทำการติดตั้ง module เพื่อการใช้งาน จากตัวอย่างสคริปท์ของผมใช้ oci8 จากการติดตั้ง ORACLE client

Input String
path_cacti  path ที่อยู่ของ cacti (ของผมคือ /usr/share/cacti มาจากการติดตั้งด้วย YUM หากท่านใช้วิธีอื่นจะไม่เหมือนกัน)

/scripts/ss_oracle_query.php ss_oracle_query คือ sub folder ใน cacti ที่ระบุถึง php สคริปท์ที่เราต้องการให้รันเพื่อ query ค่าจาก ORACLE (ss_oracle_query ตัวที่สองใช้เพื่อระบุ function ในสคริปท์ที่เราต้องการ call)

tnsnamesค่า tnsnames หรือชื่อที่เรากำหนดไว้ในไฟล์ tnsnames.ora ที่เราได้ทำการกำหนด connection description เอาไว้

path_oracle_sql เพื่อที่เราจะสามารถกำหนด SQL Statement ได้โดยอิสระสำหรับแต่ละ query ที่เราจะใช้งาน ผมจึงกำหนดให้เป็น path ที่ระบุไปยัง php ไฟล์ที่เราจะนำมา include ไปในสคริปท์ ss_oracle_query.php ที่เป็นตัวรันอีกครั้งหนึ่ง สาเหตุที่ไม่ได้ทำเป็นไฟล์ .sql หรือรับค่าเป็น statement ไปเลยก็เพราะว่าการรันใน php จะต้องทำการแก้ escape character บางอย่างเสียก่อน ไม่สามารถรันได้ทันที (สคริปท์ SQL ที่ต้องทำเป็น PHP นั้นผมจะสอนวิธีการทำ และจะนำมาแจกในบทความต่อๆไปครับ)

user username สำหรับ login เพื่อเข้าไป query ยัง Database ที่เราต้องการ

password password สำหรับ login เพื่อเข้าไป query ยัง Database ที่เราต้องการ


ตัวอย่าง php สคริปท์ที่ใช้ใน parameter path_oracle_sql
/usr/share/cacti/sql/shared_pool_free.php
<?

$query = "      select
                        round(
                                (sum(decode(name,'free memory',bytes))/sum(bytes))*100
                        ,2) as free
                from v\$sgastat
                where pool = 'shared pool'  ";

?>


Source code ของสคริปท์หลักที่ใช้เพื่อ query ข้อมูล
/usr/share/cacti/scripts/ss_oracle_query.php
<?
/* do NOT run this script through a web browser */
if (!isset($_SERVER["argv"][0]) || isset($_SERVER['REQUEST_METHOD'])  || isset($_SERVER['REMOTE_ADDR'])) {
   die("<br><strong>This script is only meant to run at the command line.</strong>");
}

/* display No errors */
error_reporting(0);

if (!isset($called_by_script_server)) {
        array_shift($_SERVER["argv"]);

        print call_user_func_array("ss_oracle_query", $_SERVER["argv"])."\n";
}

function ss_oracle_query ($tnsnames, $sql_path, $username, $password) {

        putenv("ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1");
        putenv("TNS_ADMIN=/u01/app/oracle/product/11.2.0/db_1/network/admin");

        $ret = '';

        $gdb_conn = ocilogon($username, $password,$tnsnames);

        $gdb_statement = OCIParse ($gdb_conn, "alter session set nls_date_format='MM/DD/YYYY HH24:MI:SS' ");
        OCIExecute ($gdb_statement);

        if (! OCIExecute($gdb_statement)){
                        return;
        }

        include $sql_path;

        $gdb_statement = OCIParse ($gdb_conn, $query);
        OCIExecute ($gdb_statement);

        while (OCIFetchInto ($gdb_statement, $row, OCI_RETURN_NULLS + OCI_ASSOC)) {
                reset($row);

                $shared_pool_free=$row['FREE'];
        }

        OCIFreeStatement($gdb_statement);

        $ret .= 'value:'.$shared_pool_free.' ';

        return trim($ret);
}
?>

ข้อควรระวัง
putenv("ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1");
putenv("TNS_ADMIN=/u01/app/oracle/product/11.2.0/db_1/network/admin");
2 บรรทัดนี้ในไฟล์ ss_oracle_query.php ท่านจะต้องแก้ให้ตรงกับระบบที่ท่านใช้งานในการกำหนด Environment เพื่อให้ PHP OCI8 ใช้งานในการเชื่อมต่อไปยังฐานข้อมูล ORACLE

ไม่มีความคิดเห็น:

แสดงความคิดเห็น