Socket(五)

news2024/9/28 11:17:09

文章目录

    • 1. 日志
    • 2. 如何记录日志

1. 日志

服务器要在无人看管的情况下运行很长时间,通常需要在很久以后对服务器中发生的情况进行调试,这很重要。由于这个原因,建议在存储服务器日志,至少要存储一段时间的日志。日志中通常希望记录的主要内容是:

  • 请求
  • 服务器错误

实际上,服务器一般会为这两项内容维护两个不同的日志,审计日志中,对应与服务器建立的每一个连接会分别包含一个记录,每个连接完成多个操作的服务器可能对每个操作都有一个记录。例如,dict服务器可能会为客户端查找的每个单词建立一个日志记录。错误日志则主要包含服务器运行期间发送的意外异常,主要记录程序中发生的一些异常。

2. 如何记录日志

在java1.4之前,程序基本使用的是第三方日志库,如log4j或Aache Commons Logging,之后官方提供了java.util.logging包,它能满足绝大多数需求。尽管可以根据需要来加载日志工具,不过需要最容易的办法是为每个类创建一个日志工具,如下:

private final static Logger auditLogger=Logger.getLogger("requests");

日志工具是线程安全的,所以将它们存储在共享静态字段中没有任何问题,实际上,往往需要这么做,因为即使不用在线程之间共享Logger对象,日志文件或数据块也需要共享。这在大量使用多线程的服务器中非常重要。上面的例子输出到一个名为"requests"的日志中,这个日志是什么、放在哪里取决于外部配置。它不一定是一个文件,可能是一个数据块、一个在多个服务器上运行的SOAP服务、同一个主机上运行的另一个java程序,或者是其它形式。一旦又了一个日志工具,可以使用多个方法写入这个日志。最基本的是log()。java.util.logging.Level中命名常量定义了七个级别,按严重性从高到低依次为:

  • Level.OFF
  • Level.SERVE
  • Level.WARNING
  • Level.INFO
  • Level.CONFIG
  • Level.FINE
  • Level.FINER
  • Level.FINEST
  • Level.ALL

我们通常会对审计日志使用INFO级别,对错误日志使用WARNING级别或SERVER级别。较低级别用于调试,不要在生成系统中使用。可以对各个日志使用任何方便的格式。一般来讲,每个记录应该包含一个时间戳、一个客户端地址,以及所处理的请求的任何特定信息。如果日志消息表示为一个叫错误,则要抛出特定的异常。Java会自动填入记录这个消息所在的代码位置,所以这个方面不用操心。

下面代码展示了如何为daytime服务器增加日志记录

public class QuizCardBuilder {
    private final static Logger auditLogger=Logger.getLogger("requests");
    private final static Logger errorLogger= Logger.getLogger("errors");
    public static void main(String[] args) {
        ExecutorService pool=Executors.newFixedThreadPool(50);
        try(ServerSocket server=new ServerSocket(8080)){
            while(true){
                try {
                    Socket connection=server.accept();
                    Callable<Void> task=new DaytimeTask(connection);
                    pool.submit(task);
                }catch (IOException ex){
                    errorLogger.log(Level.SEVERE,"accept  error"+ex);
                }catch (RuntimeException ex){
                    errorLogger.log(Level.SEVERE,"unexcepted error"+ex.getMessage(),ex);
                }
            }
        }catch (IOException e) {
            errorLogger.log(Level.SEVERE,"Coundn`t start server"+e);
        }catch (RuntimeException e){
            errorLogger.log(Level.SEVERE,"Coundm`t start server"+e);
        }

    }
    private static class DaytimeTask implements Callable<Void>{
        private Socket connection;
        DaytimeTask(Socket connection){
            this.connection=connection;
        }
        @Override
        public Void call() {
            try{
                Date now=new Date();
                //先写入日志记录以防万一客户端端口连接
                auditLogger.info(now+" "+connection.getRemoteSocketAddress());
                Writer out=new OutputStreamWriter(connection.getOutputStream());
                out.write(now.toString()+"\r\n");
                out.flush();
            }catch (IOException e){
               if(connection!=null){
                   try {
                       connection.close();
                   } catch (IOException ex) {
                       throw new RuntimeException(ex);
                   }
               }
            }finally {
                if(connection!=null){
                    try {
                        connection.close();
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                }
            }
            return null;
        }
    }

}

多次在终端使用Telnet与dayTime服务器通信

在这里插入图片描述

查看结果

在这里插入图片描述
上面的日志信息是直接在控制台打印的,如果我们希望将日志文件放到更加持久的位置,虽然我们可以在代码中指定,但是更好的是在配置文件中指定。这样就能改变日志位置而无需重新编译代码。java.util.logging.config.file系统属性采用常规的属性格式指向控制日志记录的一个文件。可以在启动虚拟机时加入vm配置-Djava.util.logging.config.file=_filename_参数来设置这个属性。

handlers=java.util.logging.FileHandler
java.util.logging.FileHandler.pattern=/var/logs/daytime/requests.log
java.util.logging.FileHandler.limit=10000000
java.util.logging.FileHandler.count=2
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append=true
java.util.logging.FileHandler.format=%4$s: %5$s [%1$tc]%n

上面的配置指定来下面的内容:

  • 日志要写入文件
  • 请求日志应当在/var/logs/daytime/requests.log(INFO级别)
  • 错误日志应当在/var/logs/daytime/requests.log(SERVER级别)
  • 日志大小限制为10MB,然后轮换
  • 维护两个日志:当前日志和之前的日志
  • 使用基本文本格式化工具
  • 日志的每一行采用消息级别时间戳

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/587049.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ARM微架构与程序编写

目录 1.流水线 2.指令流水线 3. 多核处理器​编辑 4. 工程搭建 4.1为Keil软件配置编译工具链 5.程序编写 5.1 数据处理指令 5.2 带标志位的加法ADC ADDS 5.3 跳转指令B\BL 5.4 单寄存器内存访问 5.5 批量寄存器内存访问 5.6 满减操作 1.流水线 2.指令流水线 3.…

算法基础学习笔记——⑭欧拉函数\快速幂\扩展欧几里得算法\中国剩余定理

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;算法基础学习 目录 ✨欧拉函数 &#x1f353;求欧拉函数 : &#x1f353;筛法求欧拉函数 : ✨快速幂 ✨扩展欧几里得算法 ✨中国剩余定理 前言&#xff1a;算法学习笔记记录日常分享&#xff0c;需要的看哈O(∩_∩)O&#…

chatgpt赋能python:Python中的倒序输出方法

Python中的倒序输出方法 在Python中&#xff0c;倒序输出是一个经常用到的操作。倒序输出可以用于字符串、列表、元组等数据类型&#xff0c;帮助我们更方便地处理数据。 字符串的倒序输出 对于字符串&#xff0c;我们可以使用字符串切片的方法倒序输出。例如&#xff0c;我…

十二、Vben之Vue3+vite跨域代理地址实现

在vue2中使用proxy进行跨域的原理是:将域名发送给本地的服务器(启动vue项目的服务,loclahost:8080),再由本地的服务器去请求真正的服务器。 代码如下: 1.在proxy中设置要访问的地址,并重写/api为空的字符串,这里如果不重写,会相当于在代理的地址上默认加了/api,所以…

chatgpt赋能python:Python中安装jieba分词器

Python中安装jieba分词器 介绍 中文分词是文本挖掘中非常重要的一个环节&#xff0c;而jieba是Python中最受欢迎的中文分词器之一。jieba分词器是基于汉语词汇库进行分词&#xff0c;并支持多种分词模式&#xff0c;可以满足不同场景的分词需求。 本文将介绍如何在Python环境…

chatgpt赋能python:Python中如何安装pip

Python中如何安装pip 什么是pip&#xff1f; pip&#xff0c;全称pip installs packages&#xff0c;是一个Python包管理工具&#xff0c;可以用来安装、升级和卸载Python包。它广泛地应用于Python社区&#xff0c;可以帮助Python开发者快速地获取和分享Python代码。 安装pi…

对比 RS232,RS422,RS485

对比 RS232,RS422,RS485 首先&#xff0c; 串口、UART口、COM口、RJ45网口、USB口是指的物理接口形式(硬件)。TTL、RS-232、RS-485、RS-422是指的电平标准(电信号)。 RS232,RS422,RS485 对比表格 通信标准RS-232RS-422RS-485工作方式单端差分差分通信线数量4 地线52 地线3节…

《深入理解计算机系统(CSAPP)》第5章 优化程序性能 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习CSAPP时的个人笔记&#xff0c;分享出来与大家学习交流&#xff0c;目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记&#xff0c;在复习回看时发现部分内容存在一些小问题&#xff0c;因时间紧张来不及再次整理…

Java中如何判断是否为闰年

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;Java经典程序设计 目录 ✨介绍 &#x1f353;引言&#xff1a;闰年的定义和在编程中的应用 &#x1f353;目的&#xff1a;介绍如何使用Java编写一个函数来判断年份是否为闰年 ✨闰年的条件 ✨提供数学原理和背景知识 &…

软考A计划-试题模拟含答案解析-卷十一

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

牛客网刷题学习SQL(三)

SQL23 统计每个学校各难度的用户平均刷题数 首先分析题目&#xff1a; 想要计算一些参加了答题的不同学校、不同难度的用户平均答题量 不同学校&#xff1a; group by 学校 不同难度&#xff1a; group by 难度 平均答题量&#xff1a;注意用户去重&#xff0c;还有指定questi…

python:绘制GAM非线性回归

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用python语言绘制广义线性模型&#xff08;Generalized Additive Model&#xff0c;GAM&#xff09;非线性回归散点图和拟合曲线。并记录了计算RMSE、ubRMSE、R2、Bias的代码。 文章目录 一、GAM非线性回归详解二、代码三、计算RM…

华为OD机试真题B卷 Java 实现【统计字符】,附详细解题思路

一、题目描述 输入一行字符&#xff0c;分别统计出包含英文字母、空格、数字和其它字符的个数。 数据范围&#xff1a;输入的字符串长度满足 1 \le n \le 1000 \1≤n≤1000 。 二、输入描述 输入一行字符串&#xff0c;可以有空格。 三、输出描述 统计其中英文字符&#…

chatgpt赋能python:Python中如何空一行

Python中如何空一行 在Python编程中&#xff0c;许多情况下我们需要在输出内容的时候空出一行。今天我们将介绍如何在Python中实现空一行的方法。 方法1&#xff1a;使用print()函数 在Python中&#xff0c;我们可以使用print()函数打印空行。我们只需在print()函数中输入两…

并发编程 原子性 可见性 有序性

并发编程的三个重要特性 原子性所谓原子性是指在一次的操作或者多次操作中&#xff0c;要么所有的操作全部都得到了执行并且不会受到任何因素的干扰而中断&#xff0c;要么所有的操作都不执行。可见性可见性是指&#xff0c;当一个线程对共享变量进行了修改&#xff0c;那么另…

chatgpt赋能python:Python中如何合并列表-详细教程

Python中如何合并列表 - 详细教程 在Python编程中&#xff0c;有时候需要把两个或多个列表合并成一个单一的列表&#xff0c;以便更好地进行数据处理。Python中有几种方法可以实现列表合并&#xff0c;本文将介绍其中的三种方法。 1. 使用“”符号 最常见的方法是使用“”符…

InsCode AI 创作助手:源于 CSDN 的 AI 创作助手,不一样的创作体验

文章目录 &#x1f4cb;前言&#x1f3af;AIGC 时代的产物&#x1f3af;InsCode AI 创作助手体验&#x1f3af;一些感受和建议&#x1f9e9;感受&#x1f9e9;建议&#xff08;个人看法&#xff09; &#x1f4dd;最后 &#x1f4cb;前言 是的没错&#xff0c;CSDN AI 写作助手…

Vue组件化开发

1. 认识组件 1.1 基础示例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widt…

STM32CubeIDE + HAL + STM32f103C8T6 系列教程1 ---板载PC13LED闪烁

STM32CubeIDE HAL STM32f103C8T6 系列教程1 --- 板载PC13LED闪烁 引言硬件关于开发板[^2]控制器内置存储器原理图 硬件连线硬件连接表硬件连线图 软件STM32CubeIDE下载及安装Stm32CubeIDE设置补全快捷键和主题新建一个工程选择开发板核心芯片型号设置工程相关参数STM32CubeMX…

最热门高效的Node.JS开源第三方开发库和特点(持续更新......)

目录 1. Express 2. Socket.io 3. Mongoose 4. Passport 5. Async 6. PM2 7. Nodemailer 8. Request 9. Cheerio 10. Lodash 11. Bluebird 12. Winston 13. Socket.io-client 14. Node-sass 15. Moment 16. Gulp 17. Grunt 18. Chai 19. Sinon 20. Nodemon…