一款简单易用的远程日志查看器,可实时查看云服务器上的日志数据

RemoteLog:远程日志 remoteLog 介绍 在开发过程中发现,有些电视设备,没有入口打开usb调试,但是又有很多奇怪bug出现,不能调试也不能开log,所以就有了这个remoteLog 项目包括后端服务器和客户端接入代码 后端服务器部分使用golang写得,前端给出了android版本的接入代码 支持 拿到后端代码自己配置服务器,需要更改html中几个ip值为自己的服务器ip android版本接入代码中可以指定上报的服务器ip 现有功能 支持多进程上报 实时上报 接入 android端接入 android接入,由于是用content provider做的多进程,需要在manifest文件中添加provider <provider android:name=".RemoteLog.RemoteLogProvider" android:authorities="org.Randy.RemoteLogPro 立即下载

本文主要内容

  • 介绍一款开发者工具(远程日志查看器)的使用说明和技术实现思路

  • 源码地址:https://github.com/HackyleShawe/RemoteLogViewer

**前置知识:**SpringBoot、SSH(Secure Shell)、WebSocket、Web前端(HTML、CSS、JavaScript、jQuery)

如果你对以上基础技术很陌生,本篇文章内容可能不适合你!

内容导览

  • 场景1:在企业级开发中,公司的测试环境一般部署在某个远程的内网服务器上,我们想要查看该个测试环境的日志,就需要手动建立SSH,再执行日志查看命令,在终端查看日志

  • 场景2:我们自己写的小项目部署到云服务器上后,想要查看日志,也需要通过SSH连接到云服务器,通过执行文件查看命令,来看到日志信息

在这个过程中:

  • 需要打开SSH客户端工具,例如MobaXterm、putty

  • 连接到远程服务器:输入密码、用户名

  • 手工键入日志文件查看命令:tail -f 日志文件路径

  • 在Shell Terminal查看日志

  • 存在问题:在Terminal上看得眼睛痛,不要根据关键字搜索日志,不好查看日志信息

在我我司的内网测试环境,查看日志

那么,有没有办法把这一过程自动化呢?答案是肯定的。这便是本项目的设计初衷与目的!

Features

  • 实时日志:可实时抓取日志文件中新产生的日志数据
  • 历史日志
    • 可查看该日志文件的历史数据
    • 在整个日志文件中进行搜索
  • 对当前页面上的日志进行关键字查询,高亮显示
  • 支持打开多个的前端页面,分别抓取日志数据渲染到页面,多个页面之间互不影响,但只能抓取一个日志文件的数据
  • 可在YML配置文件中自定义SSH服务器地址和日志文件的位置

TODO

  • 现阶段只支持获取文本文件中的日志数据,后续将可支持其他格式(例如压缩文件)的日志数据
  • 从Docker容器中捕获日志

实时日志

启动工具,进入首页,会展示所有已经配置了的日志抓取目标。点击Realtime Log,跳转到该个目标的实时日志查看页面。

点击“Start’即可开始实时抓取日志文件中新产生的日志数据

可查看该日志文件的历史数据

可实时抓取日志文件中新产生的日志数据

Start:开始抓取日志文件中的历史记录,然后实时获取新产生的日志

Stop:停止抓取

Clean:清除当前页面上的所有日志数据,但不会断开连接,还是会实时地呈现后端推送过来的日志信息

对当前页面上的日志数据进行关键字查询

  • 单击搜索框,将粘贴板上的数据复制到此个搜索框内

  • 双击搜索框,清除此个搜索框内的数据

全文件搜索

从首页进入全文件搜索页面

全文件搜索示例

本地运行

Step1:https://github.com/HackyleShawe/RemoteLogViewer

Step2:克隆项目到本地,从IDEA中打开(需要JDK17),等待Maven自动配置完毕

Step3:填写项目的配置文件(application.yml),log.targets

  • 指定SSH的连接参数:host,port,username,password

  • 远程服务器上的日志所在位置:logPath

Step4:运行启动类:RemoteLogViewerApp.java

Step5: 进入Chrome,在地址栏输入:http://localhost:8989/ ,进入日志查看首页

系统设计

前置知识

  • SpringBoot

  • SSH(Secure Shell)

  • WebSocket

  • Web前端(HTML、CSS、JavaScript、jQuery)

如果你对上述知识默认,那么这个章节你看起来可能比较吃力,但是如果你愿意一边看此项目,一边去了解相关的知识,那你一定可以掌握此项目的设计要领。

主要流程

  • 前端发起一个WebSocket连接到后端

  • 连接建立成功后,后端通过SSH连接到远程服务器

  • 执行日志文件查看命令:

    • 实时日志:tail -1f 日志文件的绝对路径,例如:tail -1f /data/log/blog-consumer.log

    • 历史日志查找:grep -E -i 关键词、正则 文件路径

  • 从SSH连接会话中,获取到该个命令的执行结果,通过WebSocket推送到前端页面上

  • 如果出现错误或被关闭,则释放WS和SSH会话

注意:在一个浏览器页面,点一次Start,开启一个WebSocket连接、一个SSH连接,当点击Stop时,关闭WebSocket连接、SSH连接。

为什么不是一个浏览器页面,一个Websocket、SSH连接?

  • 如果是这种情况,参数只能通过wbesocket的send()、handleTextMessage()方法传递

  • 第一次点击Start,会创建SSH连接,执行tail命令读取日志文件流,并保持流写出到WebSocket,

  • 第二次点击Start,会因为第一次点击的文件流没有关闭,导致第二次点击的SSH连接无法建立

  • 况且,一旦点击次数很多,那些开辟的SSH连接、tail命令的文件流累计起来,无法关闭!

缓存Websocket、SSH连接会话?

  • 当前发起WebSocket连接到后端并成功后,在后端会缓存当次Websocket、SSH连接会话

  • 数据结构:HashMap<wsSessionId, Websocket、SSH连接会话>

既然每次点击“Start”都要建立一次WS、SSH会话连接,那为什么还要缓存?

  • 页面上有一个“Stop”按钮,表示结束日志的抓取,意味着主动关闭本次WS连接

  • 那么在页面主动的关闭一个WS时,怎么找到该个WS会话呢

  • 所以在创建时就缓存下来

如何定义WS的endpoint?对外暴露ws接口?

  • 在YML中定义ws接口:endpoints: /ws/log/realtime,/ws/log/search
  • 在WS配置类(WebSocketConfig implements WebSocketConfigurer)注入

WS的参数怎么传递?

  • 前端
    • 拼接在WS的URL中
    • 等待建立连接成功后在发送
  • 后端
    • 从URL中获取:在拦截器WebSocketInterceptor捕获URL中的参数,放在WsSession的Attribute中,后续从该个attribute中get
    • 从WS会话中获取:从会话处理器中的handleTextMessage中获取

WS连接什么时候释放?

  • 出现错误或者连接被关闭时,handleTransportError,afterConnectionClosed
  • 前端发送主动关闭的信号时,通过个HTTP接口通知WS关闭

SSH连接什么时候释放? 在WS释放时

为什么不将日志目标的连接信息放置在MySQL数据库中?

  • 适用于被查看的日志目标量不大、比较固定
  • 这是一款面向开发人员的工具,而非面向普通用户。开发人员肯定懂得如何在YML配置文件中定义连接信息。
  • 为了使得本工具更加的轻量化、便捷化,尽可能地减少依赖,因此不使用MySQL数据库。

技术实现

主要流程

  1. 前端发起一个WebSocket连接到后端
  2. 连接建立成功后,后端通过SSH连接到远程服务器
  3. 执行日志文件查看命令:tail -1f 日志文件的绝对路径,例如:tail -1f /data/blog.hackyle.com/blog-business-logs/blog-business.log
  4. 获取到该个命令的执行结果,通过WebSocket推送到前端页面上

**要点:**在一个浏览器页面,点一次Start,开启一个WebSocket连接、一个SSH连接,当点击Stop时,关闭WebSocket连接、SSH连接。

为什么不是一个浏览器页面,一个Websocket、SSH连接?

  • 如果是这种情况,参数只能通过wbesocket的send()、handleTextMessage()方法传递
  • 第一次点击Start,会创建SSH连接,执行tail命令读取日志文件流,并保持流写出到WebSocket,
  • 第二次点击Start,会因为第一次点击的文件流没有关闭,导致第二次点击的SSH连接无法建立
  • 况且,一旦点击次数很多,那些开辟的SSH连接、tail命令的文件流累计起来,无法关闭!

后端

整合SSH

主要步骤

1.导入jsch的POM依赖

2.在配置文件(application.yml)中定义SSH的连接参数

3.写一个业务类,定义创建SSH会话、关闭会话的方法

​ a)使用注解(使用@Value(“${jsch.host}”))从配置文件中载入参数

​ b)创建会话方法:Session buildConnect()

​ c)关闭会话方法:void destroyConnect(Session sshSession)

application.yml中定义日志目标参数

log:
  targets:
    - code: A001 #需要唯一标识此条记录
      host: 192.168.80.25 #SSH连接参数
      port: 22
      username: root
      password: kyleshawe
      # 远程服务器上的日志文件的绝对路径
      # 例:/data/logs/app.log  #本质是执行命令"tail -10f /data/logs/app.log",查看app.log文件的后10条记录
      logPath: /data/log/blog-business.log
    - code: A002
      host: 192.168.80.25
      port: 22
      username: root
      password: kyleshawe
      logPath: /data/log/blog-consumer.log

定义实体类去映射接收: com/hackyle/log/viewer/pojo/LogTargetBean.java

注入到Spring容器: com/hackyle/log/viewer/config/LogTargetConfiguration.java


为什么不将日志目标的连接信息放置在MySQL数据库中?

  • 适用于被查看的日志目标量不大、比较固定
  • 这是一款面向开发人员的工具,而非面向普通用户。开发人员肯定懂得如何在YML配置文件中定义连接信息。
  • 为了使得本工具更加的轻量化、便捷化,尽可能地减少依赖,因此不使用MySQL数据库。

SSH工具类:使用jsch工具模拟SSH客户端,与SSH服务端建立连接

  • com/hackyle/log/viewer/util/JschUtils.java
  • Session buildSshSession (String host, int port, String username, String password) 构建并返回SSH连接会话
  • void releaseSshSession (Session sshSession) 释放一个SSH连接会话

整合WebSocket Server

主要步骤

1.导入WebSocket的starter依赖

2.事件处理器: 通过继承 TextWebSocketHandler 类并覆盖相应方法,可以对 websocket 的事件进行处理

3.WS握手(连接)拦截器

  • 通过实现 HandshakeInterceptor 接口来定义握手拦截器,完全等价于SpringMVC中的拦截器

  • 最佳应用场景是:通过拦截器可以对ws请求进行认证

4.定义ws对前端暴露的API接口

  • 通过实现 WebSocketConfigurer 类并覆盖相应的方法进行 websocket 的配置。

  • 我们主要覆盖 registerWebSocketHandlers 这个方法。

  • 通过向 WebSocketHandlerRegistry 设置不同参数来进行配置。其中 addHandler方法添加我们上面的写的 ws 的 handler 处理类,第二个参数是你暴露出的 ws 路径。

  • addInterceptors 添加我们写的握手过滤器。

  • setAllowedOrigins(“*”) 这个是关闭跨域校验,方便本地调试,线上推荐打开。

事件处理器

com.hackyle.log.viewer.ws.LogWebSocketHandler

  • 定义WebSocket的一系列回调函数

  • 使用一个静态Map缓存当前所有已经建立了连接的会话

afterConnectionEstablished方法:连接建立成功时调用

  • 创建WS会话
  • 接收前端传递的参数
  • 创建SSH连接会话
  • 根据前端传递的targetCode获取LogTargetBean
  • 缓存当前已经创建WebSocket的连接会话
  • 把WebSocket会话ID先发给前端,便于前端通过该会话ID关闭WebSocket连接
  • 调用日志获取服务,向前端推送日志数据

afterConnectionClosed方法:关闭连接后调用

  • 从缓存中移除该个已经创建了的WebSocket连接会话
握手拦截器

com.hackyle.log.viewer.ws.WebSocketInterceptor

  • beforeHandshake:在握手前触发;afterHandshake:在握手后触发。

  • 功能与SpringMVC拦截器类似

  • 这里获取前端传递来的一些参数:要查看的是那个目标的日志、这次查看多少条日志

对外暴露ws接口

com.hackyle.log.viewer.ws.WebSocketConfig

  • 定义ws对外的访问接口
  • 将事件处理器、握手拦截器注入到WebSocketHandlerRegistry
  • 设置跨域访问

实时日志数据获取与推送

com.hackyle.log.viewer.ws.LogWebSocketService

主要逻辑

  1. 准备要执行的Shell命令:tail -1f 日志文件的绝对路径,例如:tail -1f /data/blog.hackyle.com/log-business-logs/blog-business.log

  2. 获取sshSession,创建一个执行Shell命令的Channel

  3. 从Channel中读取流,包装为字符流,一次读取一行日志数据

  4. 获取WebSocket Session,只要它没有被关闭,就将日志数据通过该Session推送出去

private void sendRealtimeLogToWebSocketClient(WsSessionBean sessionDomain) throws Exception {
    WebSocketSession wsSession = sessionDomain.getWebSocketSession();
    Session sshSession = sessionDomain.getSshSession();

    //String command = "ssh tpbbsc01 \"tail -" +count+ "f " +logPath+ "\""; //二级SSH跳板机在这里修改
    String command = "tail -" +sessionDomain.getHistoryItems()+ "f " + sessionDomain.getLogTargetBean().getLogPath();
    System.out.println("command: " + command);

    //创建一个执行Shell命令的Channel
    ChannelExec channelExec = (ChannelExec) sshSession.openChannel("exec");
    channelExec.setCommand(command);
    channelExec.connect();
    InputStream inputStream = channelExec.getInputStream();

    //包装为字符流,方便每次读取一行
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
    String buf = "";
    while ((buf = reader.readLine()) != null) {
        if(wsSession.isOpen()) {
            //往WebSocket中推送数据
            wsSession.sendMessage(new TextMessage(buf));
        }
    }

    //WebSocket、SSH Session的关闭,通过本类下的‘closeWebSocketServer’方法控制
}

全文件搜索日志数据获取与推送

com.hackyle.log.viewer.ws.LogWebSocketService

主要逻辑

  1. 准备要执行的Shell命令:grep [OPTION]… PATTERN 日志文件的绝对路径,例如:grep -i “登录入参” /data/blog.hackyle.com/log-business-logs/blog-business.log

  2. 获取sshSession,创建一个执行Shell命令的Channel

  3. 从Channel中读取流,包装为字符流,一次读取一行日志数据

  4. 获取WebSocket Session,只要它没有被关闭,就将日志数据通过该Session推送出去

private void sendSearchLogToWebSocketClient(WsSessionBean sessionDomain) throws Exception {
    WebSocketSession wsSession = sessionDomain.getWebSocketSession();
    Session sshSession = sessionDomain.getSshSession();

    String keywords = sessionDomain.getKeywords();
    String[] ksArr = keywords.split("-");

    String command = "";
    if(ksArr.length == 1) { //只有一个关键字,直接搜索
        //-E:支持正则,-i:忽略大小写
        command = "grep -E -i \"" + keywords + "\" " + sessionDomain.getLogTargetBean().getLogPath();
    } else { //多个关键字
        String kws = String.join("|", ksArr);
        command = "grep -E -i \"" + kws + "\" " + sessionDomain.getLogTargetBean().getLogPath();
    }

    System.out.println("command: " + command);

    //创建一个执行Shell命令的Channel
    ChannelExec channelExec = (ChannelExec) sshSession.openChannel("exec");
    channelExec.setCommand(command);
    channelExec.connect();
    InputStream inputStream = channelExec.getInputStream();

    //包装为字符流,方便每次读取一行
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
    String buf = "";
    while ((buf = reader.readLine()) != null) {
        if(wsSession.isOpen()) {
            //往WebSocket中推送数据
            wsSession.sendMessage(new TextMessage(buf));
        }

    }
}

前端

整合WebSocket Client

WebSocket客户端

  • 初始化实例对象,打开WebSocket:var ws = new WebSocket(‘ws://localhost:8989/ws/hello’);

  • ws.readyState中枚举了不同的状态,可根据状态指定状态(ws的建立连接、发送消息、接收消息、关闭连接)的处理逻辑

  • 关闭WebSocket:ws.close();

显示历史日志的条数

抓取控制

Start:开始抓取日志文件中的历史记录,然后实时获取新产生的日志

Stop:停止抓取

Clean:清除当前页面上的所有日志数据,但不会断开连接,还是会实时地呈现后端推送过来的日志信息

为三个按钮分别添加一个Click事件,定义动作函数

Start:创建WebSocket实例,将后端发来的数据,不断追加到某个标签下

Stop:前端手动关闭WebSocket,请求后端接口,关闭WebSocket Server

页内关键字搜索

在本个页面内,进行关键字搜索。本质是模拟浏览器的Ctrl+F,进行HTML内容搜索

调用window.find()方法

  • 官方文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/find

  • API:find(aString, aCaseSensitive, aBackwards, aWrapAround, aWholeWord, aSearchInFrames, aShowDialog);

  • 参数释义

aString:将要搜索的字符串

  • aCaseSensitive:布尔值,如果为true,表示搜索是区分大小写的。

  • aBackwards:布尔值。如果为true, 表示搜索方向为向上搜索。

  • aWrapAround:布尔值。如果为true, 表示为循环搜索。

快速粘贴

单击搜索框,将粘贴板上的数据复制到此个搜索框内

  • 获取到该个搜索框

  • 调用execCommand(“copy”),把粘贴板上的数据写入

使用第三方库clipboard接管粘贴板

双击搜索框,清除此个搜索框内的数据

  • 添加一个双击事件

  • 清除元素内的值

手动关闭WS连接

背景

  • 如果直接在Client端直接关闭,在Server端会抛异常(Caused by: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。)

  • 所以,后端设计一个接口,当要关闭某个WebSocket连接时,请求该个接口,并携带上WebSocket的SessionId

设计思想

  • 在前后端建立连接时,后端就把sessionId放入缓存,并响应给前端

  • 前端得到sessionId,将其放在sessionStorage中,目的是使得该个id仅在本页面内有效

  • 前端在请求关闭接口时,携带上该个id

  • 后端移除该个id的缓存,并关闭所有会话信息

后端

接收前端请求:com/hackyle/log/viewer/controller/LogController.java

实现:com.hackyle.log.viewer.service.impl.LogServiceImpl.java#closeWebSocketServer

前端

存入sessionStorage:src/main/resources/static/js/log-realtime.js

关闭WebSocket连接时,携带sessionId:src/main/resources/static/js/index.js

打成Jar运行

背景

  • 每次需要查看日志时,都需要打开IDE环境,也挺麻烦的

  • 解决办法是将本项目打成Jar,一键启动

Step1:在POM.xml中添加打包插件

Step2:执行打包命令

Step3:将Jar放在合适的位置

Step4:写个启动脚本。本项目基于JDK17,建议手动设置临时的JDK环境变量,再启动Jar。

本文结束。

excel 利用SUBTOTAL函数计算筛选后数列总和、均值、最大、最小值 表里有三个人,咱们需要筛选出三个人,并分别计算他们的总和值。 先看一下数据范围(A1:B27) 通过筛选找张三。 按照上图所示输入函数,选择9,求和。 然后按照函数输入即可。 就能计算出结果。 筛选项选择王五,就会自动计算王五的总和。 筛选到李四就会自动计算李四的总和。 如果把9改成1,就是自动计算筛选出来的均值结果,如下图所示。 如果改成4就是取筛选项的最大值,选择5就是取最小值。 ... 阅读详情

相关推荐

达梦数据库连接报错6001网络通信异常

本文主要记录客户端连接达梦数据库报错6001网络通信异常问题分析过程、问题原因以及问题解决方法。

chen_zizi2025的博客 2768

一个支持多节点的远程服务器日志查看工具

支持多服务器多节点的远程日志查看工具

清歌词浅 798

GPS数据处理必备:IGS精密星历下载与使用全攻略(附武汉大学/CDDIS/CODE/GFZ地址)

本文为GPS/GNSS数据处理者提供了IGS精密星历的完整下载与使用指南。详细解析了最终、快速、超快速三种精密星历产品的区别与选择策略,并手把手教学如何从武汉大学、CDDIS、CODE、GFZ四大主流数据中心高效获取数据,涵盖文件命名规则解析及自动化下载脚本,助力科研与工程应用。

weixin_29234239的博客 678

remote-log-viewer:轻松管理和监控远程服务器日志

remote-log-viewer:轻松管理和监控远程服务器日志 项目介绍 在当今的互联网时代,服务器日志管理对于开发者和系统管理员而言至关重要。remote-log-viewer 是一款专为解决日志管理难题而设计的开源工具。它不仅功能强大,而且使用高效,能够帮助用户轻松管理和监控远程服务器的日志,确保系统的稳定性和安全性。 项目技术分析 remote-log-viewer 是基于 Electro...

gitblog_00660的博客 758

全网最详细单细胞保姆级分析教程(一) ---pbmc

通过观察热图,可以了解不同细胞在主成分上的分布情况,以及主成分与细胞特征之间的关系。数据归一化是数据分析中的常见步骤,旨在消除数据集中不同特征之间的量纲差异,并使它们在相同的尺度上进行比较。函数会根据指定的主成分维度计算数据点之间的距离,并找到每个数据点的邻居。函数会根据数据点之间的相似性将其分组到不同的聚类中。数据缩放是数据分析中的常见步骤,旨在将数据的特征值调整到相似的范围,以避免某些特征对分析结果的过度影响。通过可视化维度载荷,可以了解哪些特征对主成分的形成起到了重要作用,以及不同特征之间的相关性。

ZxVSaccount的博客 6704

用VINS-Fusion跑通EuRoC数据集:Ubuntu22.04+ROS2环境下的保姆级评测指南

本文详细介绍了在Ubuntu22.04和ROS2 Humble环境下使用VINS-Fusion处理EuRoC数据集的完整流程。从环境配置、数据集转换到参数调优和性能评估,提供了一套全面的多传感器融合分析方案,帮助开发者在无人机精准定位场景中实现高效部署与优化。

weixin_29212867的博客 517

探索Android开发利器:RemoteLogcatViewer

探索Android开发利器:RemoteLogcatViewer 在Android开发过程中,日志记录与分析是不可或缺的一环。 是一个强大的远程日志查看工具,它允许开发者实时、高效地监控和分析Android设备上的日志,提升开发效率。 项目简介 RemoteLogcatViewer是一个基于Java的桌面应用,通过ADB(Android Debug Bridge)连接到Android设备或模拟器,...

gitblog_00062的博客 530

中兴问天 BE7200MAX SFP 光口用华为猫棒替代光猫完整配置教程

PPPoE 账号密码:若原光猫为 Route 模式,在宽带设置页可见用户名,密码需按 F12 打开浏览器开发者模式,点击密码输入框,查看代码中 “value=” 后的内容即为明文密码。若仍失败,核对 PON 类型是否与运营商网络匹配。PON 认证信息:LOID(逻辑 ID,部分地区含密码)、设备 SN 码(标签或设备信息页)、PON 类型(GPON/EPON,运营商网络类型)。电脑保持与路由器连接,访问路由器管理地址(默认通常为 192.168.5.1,可参考路由器说明书),登录后台。

Gulper_Eel的博客 3330

WebSocket 详解--spring boot简单使用案例

WebSocket 是一种网络通信协议,专为在单个 TCP 连接上进行全双工通信而设计。WebSocket 允许客户端和服务器之间的消息能够实时双向传输。这与传统的 HTTP 请求-响应模式有很大的不同。

a2285786446的博客 3252

基于YOLOv11的仓库机器人导航系统设计与实现:Amazon Robotics Challenge解决方案

本文将详细介绍一个基于YOLOv11目标检测算法的仓库机器人导航系统,该系统能够准确识别托盘(pallet)和箱子(box),为机器人提供精确的导航信息。而基于深度学习的视觉导航系统能够实时识别环境中的关键物体,如托盘和箱子,从而实现更智能的路径规划和货物搬运。YOLOv11作为YOLO系列的最新演进版本,在检测精度和速度上都有显著提升,非常适合仓储环境中的实时物体检测任务。YOLOv11在保持实时性的同时,提高了对小物体和密集物体的检测能力,这对仓储环境中的托盘和箱子检测尤为重要。

YOLO 303

Python爬取上市公司年报并进行财务比率分析:基于异步爬虫与数据挖掘的实战

在当今数据驱动的投资时代,获取并分析上市公司财务数据对于投资者、分析师和研究人员至关重要。中国证监会指定的上市公司信息披露网站——巨潮资讯网,包含了所有A股上市公司的年报、季报及其他公告信息。本项目将展示如何使用Python最新技术栈爬取巨潮网的年报数据,提取关键财务指标,并进行深入的财务比率分析。本文将采用异步爬虫技术提高数据采集效率,使用现代解析库处理PDF和HTML文档,并结合pandas进行数据分析和可视化。整个过程将遵循合规合法的爬虫伦理,尊重网站robots.txt协议,设置合理的请求间隔。

2201_76125261的博客 666

WebSocket(java版)服务示例

WebSocket 是一种基于 TCP 的全双工通信协议,核心作用是解决传统 HTTP 协议 “请求 - 响应” 模式的局限性,实现 客户端与服务器之间的实时、双向、低延迟数据传输。

不畏惧被人讨厌而是勇往直前,不随波逐流而是激流勇进,这才是对人而言的自由。 2388

UNet 改进(27):结合SCSE注意力机制的UNet网络实现

本文介绍了一种结合SCSE注意力机制的改进UNet网络架构。该网络在保持UNet经典编码器-解码器结构基础上,通过在每层添加SCSEBlock模块,融合了通道注意力和空间注意力机制。通道注意力通过全局池化和1×1卷积生成通道权重,空间注意力则产生空间权重图,二者相加增强关键特征响应。该设计具有以下优势:1)保持原始UNet的多尺度特征提取能力;2)通过注意力机制提升对重要区域的关注度;3)计算效率高,仅增加少量参数。测试显示网络能保持输入输出分辨率不变,适用于医学图像分割等像素级预测任务。完整代码实现了5层

2401_82355416的博客 415

服务器上的文件如何查看,如何查看远程服务器上的文件

如何查看远程服务器上的文件 内容精选换一换分析辅助软件是一款支持部署到多台服务器目标环境上,实现对整个业务集群的数据采集和优化的组件。已成功登录Java性能分析。待安装分析辅助软件的服务器已开启sshd。已安装JDK并配置环境变量。打开“添加目标环境”界面,如图1所示,参数如表1所示。添加目标环境添加目标环境参数说明参数说明服务器IP地址输入待安装分析辅助软件的远程服务器的IP地云堡垒机配置了FT...

weixin_36260323的博客 2149

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

如何远程为服务器安装系统时间,如何远程为服务器安装系统

如何远程为服务器安装系统 内容精选换一换云服务器网络异常、防火墙未放行本地远程桌面端口、云服务器CPU负载过高等场景均可能导致云服务器无法正常登录。本节操作介绍无法登录Linux弹性云服务器的排查思路。当您的云服务器无法远程登录时,我们建议您首先检查是否可以通过控制台远程登录。再参考排查思路检查登录异常的原因。远程登录失败时,请首先尝试能否通过管理控制台,使用VNC方式登录弹性当云服务器网络异常、...

weixin_35564436的博客 413

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

个人站长不会 Linux 命令,怎么管理云服务器?

不会 Linux 命令,并不代表不能管理云服务器。对于个人站长来说,更合理的路线是:先用远程可视化桌面建立服务器认知,再逐步掌握必要的 SSH 命令。如果你正在寻找Linux 远程桌面SSH 远程桌面远程可视化桌面或服务器远程可视化管理工具,可以把 GMSSH 作为一个备选方案,而不是一开始就把自己困在纯命令行里。

DevCore_的博客 315

FinalShell 高效管理 Ubuntu 远程连接:从安装到故障排除全指南

本文提供FinalShell管理Ubuntu远程连接的完整指南,涵盖从软件安装、界面熟悉到SSH连接配置的全过程。重点讲解了如何为Ubuntu系统启用SSH服务、配置防火墙,并详细列出了连接失败的排查步骤与解决方案。此外,文章还介绍了如何利用FinalShell的图形化文件传输、实时服务器监控和多会话管理功能,显著提升远程工作效率。

yy01234的博客 605

【亲测免费】 推荐神器:PM2-WebShell - 远程管理你的Node.js应用从未如此简单

推荐神器:PM2-WebShell - 远程管理你的Node.js应用从未如此简单 项目简介 是一个基于 [PM2](https 的轻量级Web界面工具,它允许开发者通过浏览器远程管理他们的Node.js应用。无需安装复杂的SSH客户端或VNC,只需在运行PM2的服务器上部署此项目,即可轻松实现对应用程序的实时监控和控制。 技术分析 核心特性 安全连接:PM2-WebShell 使用HTTPS进...

gitblog_00077的博客 543

uniapp app蓝牙打印_九牧智能锁app下载-九牧智能锁下载 v0.0.58 安卓版

九牧智能锁是由九牧厨卫股份有限公司开发的一款和旗下的智能门锁相配套的软件,使用软件可以进行门锁的绑定,设置密码,解绑,修改密码等等功能,出门再也不用带钥匙,实现真正的智能生活服务,感兴趣的朋友不妨了解一下。功能介绍智能锁绑定指纹,密码及卡片录入成员管理临时密码管理报警日志查看软件特色主要通过以太网实现广域网和设备的数据通信以及控制。本软件在启动时会自动连接云服务器,进行一系列的网络操作。控制设备(...

weixin_39886956的博客 306

Java项目部署上线,公网访问

首先这篇文章从开始写,到写完战线有一个多月。四月份对于大学生来说有很多的事情,简直魔鬼月,各种比赛,学校的各种考试,还有科研立项(在这个方面博主还是很有发言权的,在博主大一的时候就用三天,赶出来一个立项书,直接评上了省级一般。。这里水很深,有空可以聊聊,如果有学弟想知道,也可以催更哦)。然后回到这篇文章,这篇文章在最开始的时候,是我第一次部署成功后就开始写了,但是写了一半就没时间了,然后临近五月份,我的计算机设计大赛推省级了,然后又要部署一下,然后这是我第二次部署了。但正是这第二次部署,让我感慨良多。

2301_79714460的博客 1449

如何用cmd命令修改服务器端口号,如何用命令行查看本地端口号

如何用命令行查看本地端口号 内容精选换一换修改/etc/slog.conf配置文件中zip_switch配置项的值为0,修改完成后,重启slogd、IDE-daemon-host进程,详细内容请参见如何重启slogd进程。登录host侧服务器,进入/var/dlog目录,使用cat命令查看日志文件内容信息。日志下载、删除等方法,类似Linux操作系统服务器上下载、删除文件的方法。配置了GPU的环境...

weixin_30320771的博客 2087

Oracle 基础知识——客户端连接oracle数据库服务端的四种方法

一,Oracle基础知识 Oracle Database11g快捷版 (Oracle Database XE) 是一款基于 Oracle Database 11g第 2 版代码库的小型入门级数据库,它具备以下优点:免费开发、部署和分发;下载速度快;并且管理简单。Oracle Database XE 是一款优秀的入门级数据库,可供以下用户使用: 致力于 PHP、Java、.NET、XML ...

Reyn_观极 1236

华为云云耀云服务器L实例评测|使用云耀云服务器L实例部署Portainer工具

华为云云耀云服务器L实例评测|使用云耀云服务器L实例部署Portainer工具

jks212454的博客 964

线上故障急救:依托 OpenClaw 日志排查 403 和 503 问题

通过正则匹配规则智能提取日志时间戳、客户端IP、请求接口路径、HTTP状态码、异常详情等核心字段,将非结构化原始日志转化为可统计、可分析的结构化数据;再次是。

Z_suger7的博客 391

推荐项目:ngrok-php - 一个基于PHP的内网穿透工具

推荐项目:ngrok-php - 一个基于PHP的内网穿透工具 去发现同类优质开源项目:https://gitcode.com/ 项目简介 是一款轻量级且高效的内网穿透工具,完全由PHP编写。它允许你在没有公网IP或者需要从外部访问本地服务器时,通过安全隧道轻松实现远程访问你的本地服务。该项目以开源的形式提供,旨在为开发者和测试人员提供便利,特别是在进行移动设备或远程协同开发时。 技术分析 工作原...

gitblog_00062的博客 758

一键部署神器---Cloud Toolkit

1、什么是 Alibaba Cloud Toolkit Alibaba Cloud Toolkit(后文简称Cloud Toolkit)可以帮助开发者更高效地部署、测试、开发和诊断应用。Cloud Toolkit与主流IDE及阿里云其他产品无缝集成,帮助您大大简化应用部署到服务器,尤其是阿里云服务器中的操作。您还可以通过其内嵌的Arthas程序诊断、Terminal Shell终端和MySQL执行器等工具,简化应用开发、测试和诊断的过程。 1.1、传统部署方式 在传统部署方式中,需要多个步骤才能完成应用的部

weixin_42956747的博客 3222

Auto DL的使用(自用)

Auto DL的使用(自用)

yansl072516的博客 2853
上一篇: “树形List“与“扁平List“互转(Java实现)
下一篇: 一种多选项的高效存取(存储、查询)解决方案
ALGO阿狗
博客等级 码龄9年 64粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值