django搭建一个小型的服务器运维网站-查看服务器中的日志与前端的datatable的利用...

目录

  1. 项目介绍和源码
  2. 拿来即用的bootstrap模板
  3. 服务器SSH服务配置与python中paramiko的使用
  4. 用户登陆与session;
  5. 最简单的实践之修改服务器时间
  6. 查看和修改服务器配置与数据库的路由
  7. 基于websocket的实时日志实现
  8. 查看服务器中的日志与前端的datatable的利用;
  9. 重启服务器进程

前言

  除了能够支持实时的日志之外,小项目还需要增加一个回看日志的页面,页面的效果如图1所示。这个页面的作用是按用户的需求(日志的日期、日志内容的时间、日志的内容)筛选出需要的日志并且展示到这个datatable的动态表格中,它的实现原理很简单,但是具有一定的局限性。但是可以满足一些本身不多的日志的查看,如错误日志、测试日志、服务器日志这些。

图1 页面效果

功能内容

显示页面

  页面由一个Datatable和自己写的一些input组件组成,其html脚本如下。

{% extends "./base.html" %}

{% block othercss %}
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet" />
{% endblock %}
{% block title %}{{ title }}{% endblock %}
{% block log %}{{ title }}{% endblock %}
{% block username %}{{ username }}{% endblock %}


{% block mainbody %}
<section class="wrapper site-min-height">
    <h3><i class="fa fa-angle-right"></i> 查找日志 <i class="fa fa-desktop"></i></h3>
    <div class="row mt">
        <div class="form-panel">
            <div class="col-lg-12 row mt">
                <div class="col-sm-6">
                    <h4 class="mb" style="float:left;dispaly:block;">查找日志</h4>
                </div>
                <div class="col-sm-5 search">
                    <input type="text" class="form-control" id='contentkey' placeholder='关键内容或日志名(可填)'>
                    <input type="text" class="form-control" id="date">
                    <div class="row">
                        <div class="col-sm-8">
                            <input type="text" class="form-control" id="time" placeholder='选择时间段(必填)'>
                        </div>
                        <div class="col-sm-4">
                            <button type="button" class="btn btn-theme02" id='searchlog' style="float:right;">查找日志</button>
                        </div>
                    </div>
                </div>
            </div>
            <div>
                <div class="progress progress-striped active" style="display:none" id="loading">
                    <div class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
                </div>
                <table id="logtable" class="table-striped dataTable table-advance table-hover" style="word-break:break-all;">
                    <thead>
                        <tr>
                            <th style="width:25%;">日志时间</th>
                            <th style="width:15%;">名字</th>
                            <th>日志内容</th>
                        </tr>
                    </thead>
                    <tbody id="log">
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</section>
{% endblock %}

  控制这个html界面的javascript代码如下,代码中laydate组件的作用是针对图2中的蓝框中的时间选择器,它的引用在文章最简单的实践之修改服务器时间中提到过,具体的使用方法可以移步文章layDate 日期与时间组件$('#logtable').DataTable({...})用来初始化一个定制的动态响应表格,后文中会具体说说它的使用。当用户填好内容之后点击查找日志按钮,会执行$("#searchlog").click(function(){...})函数,它会依次判断日期、时间段是否已经填写,由于筛选日志时候用的是时间段,所以还会判断一下首尾时间是否相等。

图2 时间选择界面

{% block scripts %}
<script>
// 获取当前的日期,在用户选择日期的时候input栏默认显示为当前日期
var formatDate = function (date) {  
    var y = date.getFullYear();  
    var m = date.getMonth() + 1;  
    m = m < 10 ? '0' + m : m;  
    var d = date.getDate();  
    d = d < 10 ? ('0' + d) : d;  
    return y + '-' + m + '-' + d;  
};  

$(document).ready(function (){
    $('#logtable').DataTable({
        "scrollCollapse": true,
        'columnDefs':[{
        'targets' : [0,1,2],    //除时间列以外都不排序
        'orderable' : false
        }],
        "order": [[0 , "asc" ]],
        "oLanguage": {
            "sZeroRecords": "无结果!",
            "sSearch": "日志过滤:",
        },
    });

    laydate.render({
        theme: 'molv',
        elem: '#date',
        // input栏默认当前日期
        value: formatDate(new Date())
    });
    // 时间范围
    laydate.render({
        theme: 'molv',
        elem: '#time',
        type: 'time',
        format: 'H点',
        range: true
    });
});
$("#searchlog").click(function(){
    keycontent = $("#contentkey").val();
    date = $("#date").val();
    if(date == ''){
        swal('', '请选择日期!', 'error')
        return ;
    }
    time = $("#time").val();
    if(time == ''){
        swal('', '请填写时间段!', 'error')
        return ;
    }
    // 判定首尾时间是否相等,由于是取时间段,首尾时间相等时是不允许的
    _time = time.split("-");
    begin_time = _time[0].replace(/\s/ig,'');
    end_time = _time[1].replace(/\s/ig,'');
    if(begin_time == end_time){
        swal('', '首位时间相等,请重新输入!', 'error')
        return ;
    }
        
    var table = $('#logtable').DataTable().clear().draw();
    table.clear().draw();
    $.ajax({
        url:"searchlog",
        type:'POST',
        data:{'keycontent':keycontent, 'date':date, 'time':time},
        success: function(arg){
            ret = eval(arg);
            logs = ret.logs;
            for(j = 0,len = logs.length; j < len; j++) {
                logtime = logs[j][0];
                logname = logs[j][1];
                logcontent = logs[j][2];
                table.row.add([logtime,logname,logcontent]).draw(true);
            }
        }
    });
});
</script>
<script src="/templates/servermaterial/assets/laydate/laydate.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
{% endblock %}

  添加server/urls.py中的url函数url(r'^searchlog', views.searchlog)
  在server/views.py中添加页面渲染函数log和由url请求过来的searchlog功能函数:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib.auth import logout
from django.shortcuts import render_to_response
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
import json
import time

'''以下这些函数是渲染前端模板的函数'''
# 服务器的名字
htmltitle = '服务器工具'


# 页面渲染函数
@login_required(login_url='/loginpage')
def log(request):
    username = request.session.get('username')
    pagedict = {'title': htmltitle, 'username': username}
    return render_to_response("servermaterial/log.html", pagedict)
    

# 查找日志
def searchlog(request):
    ret = {'status': False, 'logs': ''}
    if request.method == 'POST':
        from WebTool.functions import get_filter_log
        # 关键内容
        keycontent = request.POST.get('keycontent')
        # 日志日期
        logdate = request.POST.get('date')
        # 日志筛选的时间段
        logtime = request.POST.get('time')
        filter_list = [keycontent, logdate, logtime]
        logs = get_filter_log(filter_list)
        ret['status'] = True
        ret['logs'] = logs
    return JsonResponse(ret)

  searchlog中的get_filter_log函数是根据服务器中日志的形式单独定制的,所以在前面的文章中没有写过它的实现,下面的服务器中的日志内容中会实现一个get_filter_log函数。

服务器中的日志内容

  • 服务器中日志格式

  如图3,服务器中的日志名字规律用log-(日期)的格式存放着,每个txt日志的文档内容都形如图4所示,日志中会记录条目生成的时间,名字和内容。

图3 日志的格式

图4 日志内容格式

  • paramiko实现get_filter_log函数

  根据日志的名字规律和格式可以单独写一个paramiko函数如下,写好的函数放在Webtool/Webtool中的functions文件中。用到了一些简单的Linux命令行。
  'find /home/logs -name *' + filter_date + '*.txt'用来在日志文件夹下查找给定日期的日志文件。
  | xargs cat将查找到的结果执行cat。
  grep -E \'' + filter_time + '\' | grep -i ' + filter_content用来在cat的结果中查找符合时间段和内容的结果。
  可以看出这里,查找日志的方式是使用cat一步到位的,所以对于日志内容很大的情况,需要很长一段时间,特别是还要传递到前端的datatable中显示。

# 获得服务器的日志
def get_filter_log(filter_list):
    ssh = login_server_by_pwd()
    # 筛选日志的时期
    filter_date = filter_list[1].replace('-', '')
    _filter_date = filter_list[1]
    # 筛选日志的时间
    filter_content = filter_list[0]
    # 筛选日志的时间范围
    time_range = filter_list[2]
    beg_time, end_time = re.findall("\d+", time_range)
    beg_time = int(beg_time)
    end_time = int(end_time)
    if beg_time > end_time:
        beg_time, end_time = end_time, beg_time
    # 根据首尾时间生成每个单独时间用于日志帅选
    time_list = ["%02d" % num for num in range(beg_time, end_time)]
    filter_time = ''
    # 可被Linux执行的命令行
    for _time in time_list:
        filter_time += (_filter_date + ' ' + _time + ':|')
    filter_time = filter_time[:-1]
    # 检查是否存在该天的日志
    stdin, stdout, stderr = ssh.exec_command('find /home/logs -name *' + filter_date + '*.txt')
    istxt = bool(len(stdout.read()))
    # 如果存在改天的日志
    if istxt:
        # 如果有需要进一步筛选内容
        if filter_content:
            filter_command = 'find /home/logs -name "*' \
                             + filter_date + '*.txt" | xargs cat | grep -E \'' \
                             + filter_time + '\' | grep -i ' + filter_content
        else:
            filter_command = 'find /home/logs -name "*' \
                             + filter_date + '*.txt" | xargs cat | grep -E \'' + filter_time + '\''
            print filter_command
        stdin, stdout, stderr = ssh.exec_command(filter_command)
        raw_log = stdout.read()
        log = re.findall("\[(.*?)\]\[(.*?)\],({.*})", raw_log)
        return log

Datatable的使用

  关于Datatable的使用可以参考的文章很多,这里只是说下这个页面中dataatable的使用。它的javascript函数很简单,如下:

$('#logtable').DataTable({
    "scrollCollapse": true,
    'columnDefs':[{
        'targets' : [1,2],    // 除时间列以外都不排序,0列为时间,1列为名字,2列为内容
        'orderable' : false
        }],
    "order": [[0 , "asc" ]],  // 时间列默认按升序排列
    "oLanguage": {            
         "sZeroRecords": "无结果!",   // 表格没有内容的时候显示无结果!,如图5红色框
         "sSearch": "日志过滤:",      // 搜索栏的提示,如图5蓝色框
    },
});

图5

  下面的javascript代码通过ajax请求到后台之后,将后台传递上来的日志结果一个个增加到表格中,table.row.add([logtime,logname,logcontent]).draw(true)这个函数用来向datatable中增加数据。

$.ajax({
        url:"searchlog",
        type:'POST',
        data:{'keycontent':keycontent, 'date':date, 'time':time},
        success: function(arg){
            ret = eval(arg);
            logs = ret.logs;
            for(j = 0,len = logs.length; j < len; j++) {
                logtime = logs[j][0];
                logname = logs[j][1];
                logcontent = logs[j][2];
                table.row.add([logtime,logname,logcontent]).draw(true);
            }
        }
    });

结语

  这里说了下怎么实现查看服务器已经存在的日志,但是这个方法本身是存在缺陷的,它只适用于比较小的日志文件的显示,大文件需要很长一段时间。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值