熟悉Linux系统命令的都知道,last命令查看有哪些ip登录了本机:
现在将last -F 后输出的内容加以处理,得到以下txt文件:
现在的需求是:
判断本地IP的服务器是否重启过(reboot),重启过即为异常,否则为正常;是否为终端(tty*)登录,如果是为异常,否则为正常(pts/*)。
输出要求(例):
import pandas as pd
#路径为你文件的位置,以项目名称为根开始
dataframe = pd.read_csv(r"../../last_20200913_10.10.11.107.log", header=None, delimiter='|')
dataframe.columns=['本地IP','用户名', '终端位置', '登录ip', '开始日期', '开始时间', '结束日期', '结束时间', '持续时间']
print(dataframe)
# 1.如果用户名这一列含有reboot或者终端位置为含有tty则返回这一行
# 2.如果用户名含有root并且终端含有tty则返回这一行
# 将2.追加到1.后面
df=last_df[last_df['用户名'].isin(['reboot']) | last_df['终端位置'].str.contains('tty') ]\
.append(last_df[last_df['用户名'].isin(['root']) & last_df['终端位置'].str.contains('pts')].drop_duplicates(['本地IP'])).reset_index(drop=True)
print(df)
word_df = pd.DataFrame(columns=['服务器IP地址', '服务器重启', '本地连接', '详细信息'])
word_df['服务器IP地址']=df['本地IP']
word_df['服务器重启']=df.用户名.apply(lambda x: '异常' if 'reboot' in x else '正常')
word_df['本地连接']=df.终端位置.apply(lambda x: '异常' if 'tty' in x else '正常')
word_df['详细信息']='查看'
print(word_df)
现在有个问题,我们只需要一个IP,只要用户名中含有一个reboot就算服务器重启过,有异常;终端位置也是,只要有tty就算是有异常了。
但是现在的数据框有相同的 服务器IP地址,怎么处理才能使其变成一条呢。
我想了一个办法:利用groupby方法,将df数据框,以 本地IP 分组,将用户名和终端位置 连接到一行,然后再进行判断是否为异常。
#以本地IP分组,将用户名和终端位置 连接到一行
user_df=df.groupby(['本地IP'])['用户名'].apply(lambda x:','.join(x.values)).to_frame().reset_index()
local_df = df.groupby(['本地IP'])['终端位置'].apply(lambda x:','.join(x.values)).to_frame().reset_index(drop=True)
total_df=user_df.join(local_df)
# print('2222',user_df)
# print(local_df)
# print(total_df)
word_df = pd.DataFrame(columns=['服务器IP地址', '服务器重启', '本地连接', '详细信息'])
word_df['服务器IP地址']=total_df['本地IP']
word_df['服务器重启']=total_df.用户名.apply(lambda x: '异常' if 'reboot' in x else '正常')
word_df['本地连接']=total_df.终端位置.apply(lambda x: '异常' if 'tty' in x else '正常')
word_df['详细信息']='查看'
print(word_df)
这样就得到我们想要的结果了。
完整的实现代码:
import pandas as pd
#读文件,以| 为分隔
dataframe = pd.read_csv(r"../../last_20200913_10.10.11.107.log", header=None, delimiter='|')
dataframe.columns=['本地IP','用户名', '终端位置', '登录ip', '开始日期', '开始时间', '结束日期', '结束时间', '持续时间']
#print(dataframe)
def linux_login(last_df):
'''
:param last_df:
:return:
'''
# 1.如果用户名这一列含有reboot或者终端位置为含有tty则返回这一行
# 2.如果用户名含有root并且终端含有tty则返回这一行
# 将2.追加到1.后面
df=last_df[last_df['用户名'].isin(['reboot']) | last_df['终端位置'].str.contains('tty') ]\
.append(last_df[last_df['用户名'].isin(['root']) & last_df['终端位置'].str.contains('pts')].drop_duplicates(['本地IP'])).reset_index(drop=True)
#以本地IP分组,将用户名和终端位置 连接到一行
user_df=df.groupby(['本地IP'])['用户名'].apply(lambda x:','.join(x.values)).to_frame().reset_index()
local_df = df.groupby(['本地IP'])['终端位置'].apply(lambda x:','.join(x.values)).to_frame().reset_index(drop=True)
total_df=user_df.join(local_df)
# print('2222',user_df)
# print(local_df)
# print(total_df)
word_df = pd.DataFrame(columns=['服务器IP地址', '服务器重启', '本地连接', '详细信息'])
word_df['服务器IP地址']=total_df['本地IP']
word_df['服务器重启']=total_df.用户名.apply(lambda x: '异常' if 'reboot' in x else '正常')
word_df['本地连接']=total_df.终端位置.apply(lambda x: '异常' if 'tty' in x else '正常')
word_df['详细信息']='查看'
print(word_df)
# return word_df
linux_login(dataframe)