Thursday, May 15, 2014

Unix: Automating your server inventory

Unix systems offer many commands that can be used to pull information from your servers and help you prepare an inventory of your systems. Putting these commands into a script can be especially handy if you are managing hundreds of servers. Depending on your setup, you can run these commands remotely and collect the results in a central repository or you can run them on each server and have the results sent back to a specified location.
Some of the most useful information you will likely want to collect if you are maintaining a profile of each of the servers you manage includes:
  • the server name
  • its IP address
  • the number of CPUs and cores
  • the processor speed
  • your disk sizes
  • what OS is in use
  • the amount of memory on the system
  • the manufacturer
  • the server model
  • uptime
If you're running critical applications, you might want to collect some information on those as well. In the example systems shown below, we're also going to collect some data on the Oracle services that are running.
The basic script looks like this. In this script, we're using uname and ifconfig to get the server name and IP address and we're pulling information on the number of CPUs and cores plus the CPU speed from two of the files in the /proc file system. I've also added a check for a particular file on RedHat systems that will display the OS name to augment the build information that uname provides. Another file in /proc provides a display of how much memory the server has installed.
The script also includes a couple lshal commands to query the hardware.



echo -n "Name: "
uname -n
echo -n "IP: "
ifconfig | grep "inet addr" | grep -v | awk '{print $2}' | awk -F: '{print $2}'
echo -n "CPUs: "
grep "physical id" /proc/cpuinfo | sort | uniq | wc -l
echo -n "Cores: "
grep "^processor" /proc/cpuinfo | wc -l
echo -n "Processor speed (MHz): "
grep MHz /proc/cpuinfo | sort | awk '{print $NF}' | uniq -c
echo -n "Disk(s): "
fdisk -l | grep Disk
echo -n "OS: "
uname -o -r
if [ -f /etc/redhat-release ]; then
    echo -n "  "
    cat /etc/redhat-release
echo -n "Memory: "
grep MemTotal /proc/meminfo | awk '{print $2,$3}'
echo -n "Up for: "
uptime | awk '{print $3,$4,$5}'
echo -n "Manufacturer: "
lshal | grep system\.hardware | grep "vendor" | grep -v video | awk -F\' '{print $2}'
echo -n "Model: "
lshal | grep system\.hardware | grep "product" | grep -v video | awk -F\' '{print $2}'
The output from this script will look something like this. Notice that there's an extra line in the processor speed section.
On this particular system, one of the four CPUs is running at a different speed than the other three.
$ ./getSysInfo
CPUs: 2
Cores: 4
Processor speed (MHz):       1 2800.000
      3 3400.000
Disk(s): OS: 2.6.18-371.3.1.el5 GNU/Linux
  Red Hat Enterprise Linux Server release 5.10 (Tikanga)
Memory: 2074932 kB
Up for: 115 days, 4:28,
Manufacturer: HP
Model: ProLiant DL380 G4
To add some Oracle-specific queries, I put the queries that I wanted to run into a .sql file and then called the sql file from within my bash script. The sql file that I used looks like this and is called getVersionInstall.sql:
connect / as sysdba;
select * from v$version;
select ora_database_name from dual;
select created, sysdate from v$database;
This sql script gathers some information such as the Oracle release, the database name, and the date that the database was first set up. The output of these commands is a bit verbose (see below), so we'll store it in a file and then select only what we want to see in our script output.
SQL*Plus: Release Production on Wed May 7 10:30:37 2014

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Release - 64bit Production
With the Automatic Storage Management option


Oracle Database 11g Release - 64bit Production
PL/SQL Release - Production
CORE      Production
TNS for Linux: Version - Production
NLSRTL Version - Production


--------- ---------
11-SEP-11 12-MAY-14

Disconnected from Oracle Database 11g Release - 64bit Production
With the Automatic Storage Management option
To incorporate the database information collection into the script, I added these lines:
echo -n "Service Name: "
for file in `find $ORACLE_HOME -name tnsnames.ora -print`
    grep SERVICE_NAME $file | awk '{print $NF}' | sed "s/)//"

su -c "sqlplus '/as sysdba' @getVersionInstall.sql" oracle > ostats

grep -A 2 BANNER ostats
grep -A 2 DATABASE ostats
grep -A 2 CREATED ostats
Notice that we're getting the service name from the tnsnames.ora file and running the sqlplus command as the oracle user to get the additional information. It sends its output to a ostats file and the script then reads in portions of this file using grep -A commands to retrieve the information we are looking for.

With the added commands, the output of the script looks like this:
# ./getSysInfo
Name: oserver
CPUs: 2
Cores: 24
Processor speed (MHz): 2660.121
Disk(s): Disk /dev/sda: 1796.6 GB, 1796638507008 bytes
OS: 2.6.18-128.el5 GNU/Linux
  Red Hat Enterprise Linux Server release 5.3 (Tikanga)
Memory: 37037804 kB
Up for: 220 days, 5:49,
Manufacturer: Dell Inc.
Model: PowerEdge R710

Service Name: DEVDB

Oracle Database 11g Release - 64bit Production


--------- ---------
11-SEP-11 12-MAY-14
If you have this much information on each server, you'll have a good start on building a useful inventory. If you can add a description of each server's primary use and the people who use it (e.g., developers on the XYZ project) and enough performance data to determine how busy each server is, you'll have even more useful server profiles.

No comments:

Post a Comment