django 异步 查看 服务器日志 | 利用 channels==2.0.2

django 异步 查看 服务器日志

实例 可以查看我编写的这个项目:
https://github.com/hequan2017/chain

模块

需要安装以下模块

安装后会有一个版本号报错,不影响

channels==2.0.2
channels-redis==2.1.0
amqp==1.4.9
anyjson==0.3.3
asgi-redis==1.4.3
asgiref==2.3.0
async-timeout==2.0.0
attrs==17.4.0

cd /tmp/
wget https://files.pythonhosted.org/packages/12/2a/e9e4fb2e6b2f7a75577e0614926819a472934b0b85f205ba5d5d2add54d0/Twisted-18.4.0.tar.bz2
tar xf Twisted-18.4.0.tar.bz2
cd Twisted-18.4.0
python3 setup.py install

启动redis

原理

点击 查看日志页面,启动一个websocket连接,执行命令。

根据 登录的用户名,返回后端生成的消息,前端负责消费。


目录

chain/
        chain/
             settings.py
             asgi.py
             consumers.py
             routing.py
    templates/
           tasks/
                tail.html

settings.py

# django-channels配置
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("127.0.0.1", 6379)],
        },
    },
}

# 配置ASGI
ASGI_APPLICATION = "chain.routing.application"

consumers.py

from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer

from channels.layers import get_channel_layer

channel_layer = get_channel_layer()

class EchoConsumer(WebsocketConsumer):
    def connect(self):
        # 创建channels group, 命名为:用户名,并使用channel_layer写入到redis
        async_to_sync(self.channel_layer.group_add)(self.scope[‘user‘].username, self.channel_name)

        # 返回给receive方法处理
        self.accept()

    def receive(self, text_data):
        async_to_sync(self.channel_layer.group_send)(
            self.scope[‘user‘].username,
            {
                "type": "user.message",
                "text": text_data,
            },
        )

    def user_message(self, event):
        # 消费
        self.send(text_data=event["text"])

    def disconnect(self, close_code):
        async_to_sync(self.channel_layer.group_discard)(self.scope[‘user‘].username, self.channel_name)

asgi.py

import os
import django
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "chain.settings")
django.setup()
application = get_default_application()

routing.py

from channels.auth import AuthMiddlewareStack
from channels.routing import URLRouter, ProtocolTypeRouter
from django.urls import path

from .consumers import EchoConsumer

application = ProtocolTypeRouter({
    "websocket": AuthMiddlewareStack(
        URLRouter([
            path(r"ws/", EchoConsumer),
            # path(r"stats/", StatsConsumer),
        ])
    )
})

网页设置:

逻辑:

  1. tail页面 向后面 post 主机信息,要查看的日志路径
  2. 后端去利用 paramiko 执行命令,一直读取此接口,先返回一遍信息,如有新日志生成,再次返回给前端。
  3. 点击停止,会修改一个环境变量, 上面paramiko监测到此环境变量为false后,就停止执行命令。
 <a id="tail" class="btn btn-primary"  type="submit">查看</a>
<a id="tail_stop" class="btn btn-danger"  type="submit">不看了,必须点停止</a>

 <div class="ibox-content" >
         <pre id="output_append" ></pre>
 </div>

$(function () {

            $(document).on(‘click‘,‘#tail‘,function () {

                    $.ajax({
                        url: "{% url ‘tasks:tail_perform‘ %}",
                        timeout : 5000, //超时时间设置,单位毫秒
                        type: ‘POST‘,
                        data: $(‘.cmd_from‘).serialize(),
                        success: function (data) {
                            var obj = JSON.parse(data);
                                if (obj.status) {
                                    toastr.success("执行成功!")
                            } else {
                                 toastr.error(obj.error)
                            }

                        }
                    })
                });

              $(document).on(‘click‘,‘#tail_stop‘,function () {

                    $.ajax({
                        url: "{% url ‘tasks:tail_perform_stop‘ %}",
                        timeout : 5000, //超时时间设置,单位毫秒
                        type: ‘POST‘,
                        data: {"status":"stop"},
                        success: function (data) {
                            var obj = JSON.parse(data);
                                if (obj.status) {
                                    toastr.success("停止成功!")
                            } else {
                                 toastr.success("停止失败!")
                            }

                        }
                    })
                });
            });

 $(document).ready(function () {
    CreateWebSocket();
});

function CreateWebSocket() {
    var socket = new WebSocket(‘ws://‘ + window.location.host + ‘/ws/‘);
    socket.onmessage = function (message) {
        var result = JSON.parse(message.data);
        var status = result.status;
        var data = result.data;
        var output_html = ‘‘;
        if (status === 0) {
{#            $(‘#output_append‘).empty();#}
            output_html = data;
        }
        else if (status === 1) {
            $(‘#output_append‘).empty();
            output_html = data;
        }
        $("#output_append").prepend(output_html);
    }
}

urls.py

    path(‘tail.html‘, views.TasksTail.as_view(), name=‘tail‘),
    path(‘tailperform.html‘, views.taskstailperform, name=‘tail_perform‘),
    path(‘tailperform-stop.html‘, views.taskstailstopperform, name=‘tail_perform_stop‘),

views.py


def taillog(request, hostname, port, username, password, private, tail):
    """
    执行 tail log 接口
    """
    channel_layer = get_channel_layer()
    user = request.user.username
    os.environ["".format(user)] = "true"
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    if password:
        ssh.connect(hostname=hostname, port=port, username=username, password=decrypt_p(password))
    else:
        pkey = paramiko.RSAKey.from_private_key_file(private)
        ssh.connect(hostname=hostname, port=port, username=username, pkey=pkey)
    cmd = "tail " + tail
    stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
    for line in iter(stdout.readline, ""):
        if os.environ.get("".format(user)) == ‘false‘:
            break
        result = {"status": 0, ‘data‘: line}
        result_all = json.dumps(result)
        async_to_sync(channel_layer.group_send)(user, {"type": "user.message", ‘text‘: result_all})

def taskstailperform(request):
    """
    执行 tail_log  命令
    """
    if request.method == "POST":
        ret = {‘status‘: True, ‘error‘: None, }
        name = Names.objects.get(username=request.user)
        ids = request.POST.get(‘id‘)
        tail = request.POST.get(‘tail‘, None)

        if not ids or not tail:
            ret[‘status‘] = False
            ret[‘error‘] = "请选择服务器,输入参数及日志地址."
            return HttpResponse(json.dumps(ret))

        obj = AssetInfo.objects.get(id=ids)

        try:
            taillog(request, obj.network_ip, obj.port, obj.user.username, obj.user.password, obj.user.private_key, tail)
        except Exception as e:
            ret[‘status‘] = False
            ret[‘error‘] = "错误{0}".format(e)
            logger.error(e)
        return HttpResponse(json.dumps(ret))

def taskstailstopperform(request):
    """
    执行 tail_log  命令
    """
    if request.method == "POST":
        ret = {‘status‘: True, ‘error‘: None, }
        name = request.user.username
        os.environ["".format(name)] = "false"
        return HttpResponse(json.dumps(ret))


django 异步 查看 服务器日志 | 利用 channels==2.0.2

原文地址:http://blog.51cto.com/hequan/2114529

时间: 2024-11-06 03:05:18

django 异步 查看 服务器日志 | 利用 channels==2.0.2的相关文章

SSH查看服务器日志常用语句

SSH客户端查看服务器日志常用语句即为linux进行文件夹进行文件查看的常用语句: 1.cd 2.tail 3.grep [options] pattern file -c:只输出匹配行的计数.-I:不区分大 小写(只适用于单字符).-h:查询多文件时不显示文件名.-l:查询多文件时只输出包含匹配字符的文件名.-n:显示匹配行及 行号.-s:不显示不存在或无匹配文本的错误信息.-v:显示不包含匹配文本的所有行. 面对庞大的日志文件,单独下载并打开文件,从中提取信息的话,很吃力.这时,grep语句

一个j2ee测试神器,方便查看服务器日志的工具

功能: 1,能够将服务器上的指定的文件通过浏览器倒序显示处理,如果文件是系统日志,则可以用来查日志信息. 2,可以倒序显示指定的行数,默认100行,通过参数count=500可以修改显示行数. 3,只按行显示行数,默认最大10000行,支持大文件或超大文件,就算文件有1G. 4,可以与操作事件配合,执行一个动作,刷一下就能查看最新的. 5,结合浏览器本身的查找功能,可以方便查找想要的信息. 其他功能: 1,filter支持关键字查询,如:filter=findData,则只显示含有findDat

支持异步写入的日志类,支持Framework2.0

因为工作需要需要在XP上运行一个C#编写的Winform插件,我就用Framework2.0,因为存在接口交互所以想保留交易过程的入参出参. 考虑到插件本身实施的因素,就没有使用Log4.NLog等成熟的日志插件.在网上搜索了一个是通过TextWriterTraceListener实现的,但是实际使用 过程中发现并没实现我想要的功能,于是乎自己重新造了个轮子,如果大家有需要可以参考下. 1 /// <summary> 2 /// 日志类型 3 /// </summary> 4 pu

前段时间,接手一个项目使用的是原始的jdbc作为数据库的访问,发布到服务器上在运行了一段时间之后总是会出现无法访问的情况,登录到服务器,查看tomcat日志发现总是报如下的错误。    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected est

前段时间,接手一个项目使用的是原始的jdbc作为数据库的访问,发布到服务器上在运行了一段时间之后总是会出现无法访问的情况,登录到服务器,查看tomcat日志发现总是报如下的错误. Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too man

Linux服务器限制ssh登录,查看登录日志

网络上的服务器很容易受到攻击,最惨的就是被人登录并拿到root权限.有几个简单的防御措施: 1. 修改ssh服务的默认端口 ssh服务的默认端口是22,一般的恶意用户也往往扫描或尝试连接22端口.所以第一步就是修改这个默认端口 打开/etc/ssh/sshd_config,找到 Port 22 然后将22修改为其它没有被占用的端口,如1022.最好在1-1024之间,防止与用户进程端口冲突. 然后重启sshd即可 sudo /etc/init.d/ssh restart 2. 限制IP 首先修改

Nginx+uWSGI+Django部署web服务器

目录 Nginx+uWSGI+Django部署web服务器 环境说明 前言 搭建项目 Django部署 编辑luffy/luffy/settings.py 编辑luffy/app01/views.py 编辑luffy/luffy/urls.py 运行并测试 uWSGI部署 测试运行uWSGI 使用uWSGI运行django项目 uWSGi热加载Djangoa项目 部署nginx nginx配置uwsgi和django django部署static文件 重新加载nginx进行测试 测试nginx

Linux服务器 -- 日志篇

志对于安全来说,非常重要,它记录了系统每天发生的各种各样的事情,你可以通过他来检查错误发生的原因,或者受到攻击时攻击者留下的痕迹.日志主要的功能有:审计和监测.他还可以实时的监测系统状态,监测和追踪侵入者等等.正因为如此,抚琴煮酒特的将它整理成一篇比重跟硬件篇.网络篇并列的文章,作为<明明白白你的Linux服务器>系列的第三篇,希望大家能从中学习到对自己有用的东西. 一.配置syslog(gyl4802959同学撰写) 目前,linux依旧使用syslogd作为日志监控进程,对其进行必要的配置

web站点服务器日志管理及分析

管理Web网站不只是监视Web的速度和Web的内容传送.它不仅要关注服务器每天的吞吐量,还要了解这些Web网站的外来访问,了解网站各页面的访问情况.根据各页面的点击频率来改善网页的内容和质量,提高内容的可读性,以及跟踪包含有商业交易的步骤及管理Web网站"幕后"的数据等. 为了更好地提供WWW服务,监控Web服务器的运行情况.了解网站内容的详细访问状况就显得越来越重要和迫切了.而这些要求都可以通过对Web服务器日志文件的统计和分析来实现.本文将对Web服务器日志分析的原理和技术进行讨论

[转]Oracle DB 查看预警日志

"Database(数据库)"主页>"Related Links相关链接)"区域> "Alert Log Content (预警日志内容)" 查看预警日志 每个数据库都有一个alert_<sid >.log文件.此文件位于数据库所在的服务器中,如果设置了$ORACLE_BASE,则此文件默认存储在$ORACLE_BASE/diag/rdbms/<db_name>/<SID>/trace中. 数据库预