Sunday, August 26, 2012

Join() method in Python Threading


Python Docs for join():
Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception – or until the optional timeout occurs.

A nice explanation available at: http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread-management.html

Imagine the following scenario. You are preparing for tomorrow's final examine and feel a little hungry. So, you give your younger brother ten bucks and ask him to buy a pizza for you. In this case, you are the main thread and your brother is a child thread. Once your order is given, both you and your brother are doing their job concurrently (i.e., studying and buying a pizza). Now, we have two cases to consider. First, your brother brings your pizza back and terminates while you are studying. In this case, you can stop studying and enjoy the pizza. Second, you finish your study early and sleep (i.e., your assigned job for today - study for tomorrow's final exam - is done) before the pizza is available. Of course, you cannot sleep; otherwise, you won't have a chance to eat the pizza. What you are going to do is to wait until your brother brings the pizza back. This is exactly the problem and solution we mentioned at the end of the previous section.

Thread join is designed to solve this problem. A thread can execute a thread join to wait until the other thread terminates. In our case, you - the main thread - should execute a thread join waiting for your brother - a child thread - to terminate. In general, thread join is for a parent to join with one of its child threads. Thread join has the following activities, assuming that a parent thread P wants to join with one of its child threads C.

When P executes a thread join in order to join with C, which is still running, P is suspended until C terminates. Once C terminates, P resumes.
When P executes a thread join and C has already terminated, P continues as if no such thread join has ever executed (i.e., join has no effect).
A parent thread may join with many child threads created by the parent. Or, a parent only join with some of its child threads, and ignore other child threads. In this case, those child threads that are ignored by the parent will be terminated when the parent terminates.

import threading
import time

threads = []
class myThreading(threading.Thread):
    def __init__(self,counter):
        threading.Thread.__init__(self)
        self.counter=counter
     
    def run(self):
        print "In :" + self.name
        self.someFun(self.counter)
        print "Out :" + self.name
 
    def someFun(self,counter):
        time.sleep(counter)

a=myThreading(5)
a.start()
b=myThreading(1)
b.start()

threads.append(a)
#threads.append(b)

for t in threads:
    t.join()
 
print "main"


The main thread will wait for "a" to finish before printing "main".

Threading in Python


By import threading :

acc. to Python Docs:
Threads can be created by passing a callable object to the constructor, or by overriding the run() method in a subclass.

1) overriding the run() method in a subclass

import threading
import time

class myThreading(threading.Thread):
    def __init__(self,counter):
        print "In init__"
        self.counter=counter
        threading.Thread.__init__(self)
   
    def run(self):
        print "in Run " + self.name
        tFunc(self.name,self.counter)
        #time.sleep(1)
   
    def pCount(self):
        print threading.activeCount()
        #print threading.enumerate()
       
def tFunc(name,counter):
    while counter :
        print "Name:" + name
        counter -= 1
       
tObj1=myThreading(2)
tObj1.start()


start() starts the thread activity. It arranges for the object’s run() method to be invoked in a separate thread of control.

start() will create a thread. run() function will be executed in tht thread
tObj1.run() will not create thread. It will simply execute run method of same class.
Or in other words tObj1.run() will just call run() function  in the current (calling) Thread.

2) passing a callable object to the constructor

import threading
import time

class myThreading(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self,target=tFunc,name='tName',args=(2,))

def tFunc(counter):
    while counter:
        print "Count :", counter
        counter -= 1
       
tObj1=myThreading()
tObj1.start()

Friday, July 27, 2012

How to edit /etc/resolv.conf in Solaris 11?



In Solaris 11 the /etc/resolv.conf is (automatically) populated with svc:/network/dns/client service.
Modifications will be lost when the svc:/network/dns/client service is restarted.

root@smfSolaris11:~/jms# cat /etc/resolv.conf

#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
#

#
# _AUTOGENERATED_FROM_SMF_V1_
#
# WARNING: THIS FILE GENERATED FROM SMF DATA.
#   DO NOT EDIT THIS FILE.  EDITS WILL BE LOST.
# See resolv.conf(4) for details.

search  smf.com
nameserver      x.x.x.x
nameserver      x.x.x.y

Step:

svc:/network/dns/client> listprop config
config                      application
config/value_authorization astring     solaris.smf.value.name-service.dns.client
config/nameserver          net_address x.x.x.x x.x.x.y
config/search              astring     smf.com
svc:/network/dns/client> setprop config/search = symcsmf.com
svc:/network/dns/client> listprop config
config                      application
config/value_authorization astring     solaris.smf.value.name-service.dns.client
config/nameserver          net_address x.x.x.x x.x.x.y
config/search              astring     symcsmf.com
svc:/network/dns/client> exit
root@smfSolaris11:~/jms# svcadm refresh dns/client
root@smfSolaris11:~/jms# svcadm restart dns/client
root@smfSolaris11:~/jms# cat /etc/resolv.conf

#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
#

#
# _AUTOGENERATED_FROM_SMF_V1_
#
# WARNING: THIS FILE GENERATED FROM SMF DATA.
#   DO NOT EDIT THIS FILE.  EDITS WILL BE LOST.
# See resolv.conf(4) for details.

search  symcsmf.com
nameserver      x.x.x.x
nameserver      x.x.x.y



To change
- nameserver: setprop config/nameserver = (192.168.1.1 4.2.2.2 8.8.8.8)
- domain: setprop config/domain = smthing.com


More reference : http://timwort.org/classp/TS11_HTML/mod06.htm

Monday, July 23, 2012

Monitoring log files with Zabbix

What I wanted:
Zabbix should send me mail when string "ERROR" is seen in log file.

Approach:
We create a Item which monitors log files (looks for "ERROR" string at specified interval).
We then create a Trigger on this Item. Trigger creates and event.
In the end, we tell what Zabbix should do once the trigger is triggered (or event is created). In my case, I needed an email.

Steps:


- Specify ServerActive=<Zabbix_server_ip>:<server_port> in conf file if you have Zabbix 2.0. For Zabbix 1.8, this parameter is not needed. (Default server port is 10051). Start Zabbix Agent (steps).


- Create a template. Create an Item to monitor log file in that template.



    Key = log[/var/log/error_file,ERROR,,1] and type of information = Log and
    Type = Zabbix Agent Active

- Create a Trigger for this Item


  Expression = {testtemplate:log[/var/log/error_file,ERROR,,1].str(ERROR)}=1
  PS: I want to Zabbix to look for "ERROR" string. You can use any value here(E.g: OutOfMemoryError).

- Create an action for this tirgger:


  PS: You can add more conditions like Host = hostname etc. 

- I have specified Send message to Group "Zabbix administrators" in my action. By default, "Zabbix administrators" group has only one user Admin added in it. 
Goto Administration -- > Users. Look for "Zabbix administrators" group
Click on User Admin and add a valid media i.e. email address where you want your alerts to come.

- Now go to Administation --> Media Type and add your mail server details.

Whenever "Error" word is seen is log file, Log Item catches it and trigger is triggered. Trigger's action is set to send an email to  "Zabbix administrators" group where we provided valid email address.






Tuesday, July 17, 2012

Starting Zabbix Agent on Linux

Get Pre-compiled Zabbix agents from here
Add user Zabbix
#useradd  -c 'Zabbix monitoring' zabbix

Start agent service (as zabbix user)
sbin/zabbix_agentd -c /home/zabbix/server.conf
(Agent wont start with # prompt; login with "zabbix" before starting agent)

Server.conf file:
[zabbix@test ~]$ cat server.conf
Server=<ip_of_zabbix_server>
Hostname=test.smf.com
LogFile=/tmp/zabbix_agentd.log


Make sure you specify correct hostname in
- conf file before starting agent.
- Zabbix UI while adding the host.

In my case, I have:
[zabbix@test ~]$ hostname
test.smf.com
[zabbix@test ~]$

Hence, I gave test.smf.com in my conf file. And while adding host in zabbix UI, same name was specified.
You will get "active check errors" in client log file if proper hostname is not provided. Moreover, Zabbix Agent (Active) too will not work.
( Zabbix Agent (Active) is needed if you want to monitor log files)



Sample outputs:

[zabbix@test ~]$ cat /tmp/zabbix_agentd.log
 16494:20120718:052501.334 Starting Zabbix Agent [test.smf.com]. Zabbix 2.0.0 (revision 27675).
 16495:20120718:052501.335 agent #0 started [collector]
 16496:20120718:052501.337 agent #1 started [listener]
 16497:20120718:052501.337 agent #2 started [listener]
 16498:20120718:052501.338 agent #3 started [listener]
[zabbix@test ~]$

[zabbix@test ~]$ ps -ef | grep zabbix
zabbix   16494     1  0 05:25 ?        00:00:00 sbin/zabbix_agentd -c /home/zabbix/server.conf
zabbix   16495 16494  0 05:25 ?        00:00:00 sbin/zabbix_agentd -c /home/zabbix/server.conf
zabbix   16496 16494  0 05:25 ?        00:00:00 sbin/zabbix_agentd -c /home/zabbix/server.conf
zabbix   16497 16494  0 05:25 ?        00:00:00 sbin/zabbix_agentd -c /home/zabbix/server.conf
zabbix   16498 16494  0 05:25 ?        00:00:00 sbin/zabbix_agentd -c /home/zabbix/server.conf