0

We're using Splunk (A tool to analyse machine data like log files) and have an application in PHP. For some data we need to do a call to our application in php (CLI-based). Unfortunately Splunk only supports Python calls.
Is there an easy way to 1:1 "forward/call" php with the same arguments and return the output, like a "passthru". I've found only parts of the solution with the socalled subprocess module but my python experience is zero, so can't get it to work.

For example, splunk calls:
python external_lookup.py argument1 argument2 argument3
- Then the python script should call (with the CLI arguments given to python):
php external_lookup.php argument1 argument2 argument3
- Then php writes its output
- Python captures that output and outputs it itself

Any help much appreciated, or a working example script even better.

Thanks in advance,
Vince

  • It looks like Splunk has a nice RESTful API that you can use from any language. http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTcontents – Andbdrew Sep 21 '12 at 18:36
  • `os.system('php external.php %s'%' '.join(sys.argv[1:]))` ... maybe... – Joran Beasley Sep 21 '12 at 18:40
  • Thank you, that's in relation to search etc. (Different functionality) Our problem is in relation to indexing and field lookups. It is described here for python (which is the only language supported for that functionality): http://docs.splunk.com/Documentation/Splunk/4.3.4/Knowledge/Addfieldsfromexternaldatasources#Set_up_a_fields_lookup_based_on_an_external_command_or_script – Vince Meens Sep 21 '12 at 18:41
  • Thanks Joran, I tried to get it to work, but didn't work instantly so I was trying to figure it out by reading the python documentation on os.system etc. but then xiaomao already posted a solution that worked. Thanks for the effort. – Vince Meens Sep 21 '12 at 19:16

2 Answers2

1

Using Popen from the subprocess module:

import sys
from subprocess import Popen
output = subprocess.Popen(['php', 'path/to/script.php'] + sys.argv[1:], stdout=subprocess.PIPE).communicate()[0]

sys.argv[1:] contains every command line argument except the name of python script itself.

knittl
  • 246,190
  • 53
  • 318
  • 364
  • You code doesn't specify the PHP script to execute, and it outputs all the output when the PHP script terminates. – quantum Sep 21 '12 at 18:59
  • @xiaomao: as far as I understood the question, the OP wants to get all output from the PHP script. – knittl Sep 21 '12 at 19:07
  • I think it's a better idea to output real time. But that's not the point. Your code is fundamentally wrong. `subprocess.Popen` is not even a valid identifier in this case. – quantum Sep 21 '12 at 19:10
  • Thanks knittl, I tried it and indeed found out that I had to switch import Popen from subprocess to from subprocess import Popen, but then somehow still got a syntax error on the *sys.argv[1:] trying to debug it. And then xiaomao's solution was posted already which works. Thanks again. – Vince Meens Sep 21 '12 at 19:13
0

Using subprocess.call:

import sys, subprocess
sys.exit(subprocess.call(['php', sys.argv[0].replace('.py', '.php')] + sys.argv[1:]))

Edit: Made Python script return the value the PHP script returned.

quantum
  • 3,672
  • 29
  • 51
  • Thanks, this does the trick instantly :-). Now we can keep working in our main language rather than mixing the code base too much. It'll open up a lot of good stuff to splunk, for example if the log file contains a user_ID we can substite it with their names, and then make reports from it which are human friendly. – Vince Meens Sep 21 '12 at 19:15
  • Can you also forward the stdin in the same statement? Making it completely proxy all possible input? (I just found out that in some cases splunk also uses stdin...) Something like appending + ' < ' sys.stdin.read() I'm guessing but not sure if that'll work with strings and line endings properly. Thanks in advance. – Vince Meens Sep 22 '12 at 12:31
  • @VinceMeens I believe `subprocess.call` will forward all streams (stdin, stdout, and stderr) unless told not to. – quantum Sep 22 '12 at 12:50
  • You're right... my mistake. I was already capturing the stdin in my python script to debug it to a file, so therefor it wasn't forwarded. Thanks again. – Vince Meens Sep 22 '12 at 13:03