0

I am working on a Python script that will allow me to better find specific syslogs files. The script simply consists in typing the IP address of the concerned machine and then the date (in YYYYMMDD format) since there is one log file per day on the server..

The script is largely copied and adapted from a similar script that a colleague programmer did before me. But I don't have as much expertise as he does on Python, and he didn't leave comments on his code.

# This Python file uses the following encoding: utf-8
import os, sys, re
name = raw_input("IP Address? \n")

dir = os.listdir(os.getcwd())

flag_equip = False
flag_h_start = True
flag_h_end = True
flag_date = True
for n in dir :
        if(n!="syslog_hosts" and n!="syslog_hosts.avec.domain" and n!="syslog_hosts.BKP"):
                for nn in os.listdir("/applis/syslog/syslog_cpe"):
                        if(re.search(name,nn)):
                                flag_equip = True
                                print("Equipment found!")
                                while(flag_date):
                                    date = raw_input("date AAAAMMJJ ?\n")
                                    if(re.search("[\d]{8}$",date)):
                                        flag_date = False
                                for nnn in os.listdir("/applis/syslog/syslog_cpe"+"/"+n+"/"+nn):
                                        raw_filename = nnn.split(".")
                                        for i in raw_filename :
                                                if(i==date):
                                                        break
          
         
          
         
if(flag_equip==False):
        print("Equipment not found")

I have a problem with the part where I have to enter the date. No matter what I put in the date, it always gives me this error below. The IP address matches the one I entered but not the date which is always the first one of the machine.

  File "scriptsyslog.py", line 21, in <module>
    for nnn in os.listdir("/applis/syslog/syslog_cpe"+"/"+n+"/"+nn):
OSError: [Errno 2] No such file or directory:'/applis/syslog/syslog_cpe/.bash_history/100.117.130.80.20220404.log'

My code may seem a bit strange but that's because it's not complete. I hope that's clear enough. The log files are all named in the format "[IP address][YYYYMMDD].log" For example 100.117.130.80.20220410.log

Thank you in advance. This is my first question on StackOverflow.

Kevin.T
  • 52
  • 1
  • 9
  • It's not clear why you are looping over files in the current directory in the first place if you actually want to examine a different directory. As the error message reveals, you have looped over your home directory and picked up the `.bashrc` file as the first file from `os.listdir()`. (Coincidentally, the `os.getcwd()` is completely superfluous here. Perhaps see also [What exactly is current working directory?](https://stackoverflow.com/questions/45591428/what-exactly-is-current-working-directory) which might actually also solve your problem, I'm guessing.) – tripleee Apr 12 '22 at 14:17
  • `raw_input` is Python 2, are you sure you want to stay on this unsupported and increasingly unpopular version of Python? The currently recommended and supported version of the language is Python 3. Python 2 went out of support in 2020, and many of us thought that was several years too late. – tripleee Apr 12 '22 at 17:32

1 Answers1

0

Here's an attempt to fix the script.

Rather than require interactive I/O, this reads the IP address and the date as command-line arguments. I think you will find that this is both more user-friendly for interactive use and easier to use from other scripts programmatically.

I can't guess what your file and directory tree looks like, but I have reimplemented the code based on some guesswork. One of the hard parts was figuring out how to give the variables less misleading or cryptic names, but your question doesn't explain how the files are organized, so I could have guessed some parts wrong.

Your original script looks like you were traversing multiple nested directories, but if your prose description is correct, you just want to scan one directory and find the file for the specified IP address and date. This simply assumes that you have all your files in /applis/syslog/syslog_cpe and that the scanning of files in the current directory was an incorrect, erroneous addition to a previously working script.

# Stylistic fix: Each import on a separate line
import os
import sys

if len(sys.argv) != 3:
    print("Syntax: %s <ip> <yyyymmdd>" % sys.argv[0].split('/')[-1])
    sys.exit(1)

filename = os.path.join(
    "/applis/syslog/syslog_cpe",
    sys.argv[1] + "." + sys.argv[2] + ".log")
if os.path.exists(filename):
    print(filename)
else:
    # Signal failure to caller
    sys.exit(2)

There were many other things wrong with your script; here is an attempt I came up with while trying to pick apart what your script was actually doing, which I'm leaving here in case it could entertain or enlighten you.

# Stylistic fix: Each import on a separate line
import os
import sys
import re


# Stylistic fix: Encapsulate main code into a function
def scanlog(ip_address, date, basedir="/applis/syslog/syslog_cpe"):
    """
    Return any log in the specified directory matching the
    IP address and date pattern.
    """
    # Validate input before starting to loop
    if not re.search(r"^\d{8}$", date):
        raise ValueError("date must be exactly eight digits yyyymmdd")
    if not re.search(r"^\d{1,3}(?:\.\d{1,3}){3}$", ip_address):
        raise ValueError("IP address must be four octets with dots")

    for file in os.listdir(basedir):
        # Stylistic fix: use value not in (x, y, z) over value != x and value != y and value != z
        # ... Except let's also say if value in then continue
        if file in ("syslog_hosts", "syslog_hosts.avec.domain", "syslog_hosts.BKP"):
            continue
        # ... So that we can continue on the same indentation level
        # Don't use a regex for simple substring matching
        if file.startswith(ip_address):
            # print("Equipment found!")
            if file.split(".")[-2] == date:
                return file
    # print("Equipment not found!")


# Stylistic fix: Call main function if invoked as a script
def main():
    if len(sys.argv) != 3:
        print("Syntax: %s <ip> <yyyymmdd>" % sys.argv[0].split('/')[-1])
        sys.exit(1)
    found = scanlog(*sys.argv[1:])
    if found:
        print(found)
    else:
        # Signal error to caller
        sys.exit(2)

if __name__ == "__main__":
    main()

There is no reason to separately indicate the encoding; Python 3 source generally uses UTF-8 by default, but this script doesn't contain any characters which are not ASCII, so it doesn't even really matter.

I think this should work under Python 2 as well, but it was written and tested with Python 3. I don't think it makes sense to stay on Python 2 any longer anyway.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    I am speechless, I did not expect such a great help. I may have forgotten to mention it in my original message but the purpose of my script is to display the content of the selected log file on the screen, but I think I can handle that part by myself now. Thanks a lot for your help! – Kevin.T Apr 13 '22 at 07:28
  • `less "$(this script "$@")"` – tripleee Apr 13 '22 at 07:39
  • I'm sorry to ask for your help again, but where should I place this line of code? After line 13? – Kevin.T Apr 13 '22 at 08:03
  • No, this is a new command which uses this script to produce the file name. Probably create a function in your `.bashrc` or similar `showlog () { less "$(findlog "$@")"; }` where we assume `findlog` is the name you gave this script and that it's saved to a directory in your `PATH`. There are many beginner questions about how to save and run Python scripts, though very basic questions about how to use the command line are not really suitable for Stack Overflow. – tripleee Apr 13 '22 at 08:06
  • In other words, if `findlog 12.34.56.78 20220401` produces `/applis/syslog/syslog_cpe/12.34.56.78.20220401.log` then `showlog 12.34.56.78 20220401` would run `less /applis/syslog/syslog_cpe/12.34.56.78.20220401.log`. (Of course, you don't really need Python for this; `showlog () { less "/applis/syslog/syslog_cpe/$1.$2.log"; }` is much simpler and more elegant.) – tripleee Apr 13 '22 at 08:09