【运维知识大神篇】超详细的ELFK日志分析教程5(Logstash中Filter常用插件详解+实战练习)

news2024/11/16 13:49:21

本篇文章主要讲解logstash的有关内容,包括filter的grok、date、user_agent、geoip、mutate插件,多个输入输出方案(多实例+if多分支语句),每个知识点都涉及实战练习,在实战中学习,事半功倍!

Filter常用插件详解

一、grok使用官方模块采集nginx日志

参考官网链接:https://www.elastic.co/guide/en/logstash/7.17/plugins-filters-grok.html

1、删除缓存数据,删除后会重新读取文件,注意删除前先停掉logstash

[root@ELK102 ~]# ll /usr/share/logstash/data/plugins/inputs/file/.sincedb_
.sincedb_d527d4fe95e50e89070186240149c8bb
.sincedb_df5ae0d18161177fc305494571a52fca
.sincedb_e516aafddd2f065b257550d46b8c954c
[root@ELK102 ~]# rm -rf /usr/share/logstash/data/plugins/inputs/file/.sincedb_*

2、编写配置文件

[root@ELK102 ~]# cat /etc/logstash/conf.d/04-nginx-to-es.conf
input { 
  file {
    start_position => "beginning"
    path => ["/var/log/nginx/access.log*"]
  }
}  

filter{
  grok{
    match => {
      "message" => "%{COMMONAPACHELOG}"    #官方自带的Apache转换模块,与nginx格式一致
    }
  }
}

output { 
  elasticsearch {
    hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19200"]
    index => "koten-nginx-%{+yyyy.MM.dd}" 
  } 
  stdout {} 
}

3、执行logstash查看grok转换结果

[root@ELK102 ~]# logstash -rf /etc/logstash/conf.d/04-nginx-to-es.conf
......
{
       "@version" => "1",
        "message" => "10.0.0.1 - - [29/May/2023:11:26:09 +0800] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.50\" \"-\"",
           "path" => "/var/log/nginx/access.log",
       "clientip" => "10.0.0.1",
           "host" => "ELK102",
        "request" => "/",
     "@timestamp" => 2023-05-29T03:26:20.756Z,
           "verb" => "GET",
       "response" => "304",
           "auth" => "-",
    "httpversion" => "1.1",
          "ident" => "-",
      "timestamp" => "29/May/2023:11:26:09 +0800",
          "bytes" => "0"
}

二、grok自定义正则案例

1、准备待匹配文本数据

[root@ELK102 ~]# cat /tmp/haha.log 
welcome to kotenedu linux, 2023

2、编写自定义的匹配模式

[root@ELK102 ~]# mkdir koten-patterns/koten-patterns
[root@ELK102 ~]# cat koten-patterns/koten.patterns 
SCHOOL [a-z]{8}
SUBJECT [a-z]{5}
YEAR [\d]{4}

3、编写grok的使用自定义匹配模式

[root@ELK102 ~]# cat config/05-file-grok-stdout.conf 
input { 
  file {
    start_position => "beginning"
    path => ["/tmp/haha.log"]
  }
}  

filter {
  # 基于正则匹配任意文本
  grok {
    # 加载自定义变量的存储目录
    patterns_dir => ["./koten-patterns/"]

    match => {
      "message" => "welcome to %{SCHOOL:school} %{SUBJECT:subject}, %{YEAR:year}"
    }
  }
}

output { 
  stdout {
    codec => rubydebug 
  } 
}

4、启动logstash,注意,启动logstasg案例,为防止写入时多个案例调用同一个id的文档,导致数据少写,官方限制了多个案例同时启动,需要单独指定数据路径

[root@ELK102 ~]# logstash -rf /etc/logstash/conf.d/05-nginx_file-grok-stdout.conf 
......
{
       "message" => "welcome to kotenedu linux, 2023",
        "school" => "kotenedu",
       "subject" => "linux",
          "year" => "2023",
    "@timestamp" => 2023-05-29T12:01:33.003Z,
          "host" => "ELK102",
      "@version" => "1",
          "path" => "/tmp/haha.log"
}

[root@ELK102 ~]# logstash -rf /etc/logstash/conf.d/05-nginx_file-grok-stdout.conf --path.data /tmp/new-data    #单独指定数据路径

三、date插件修改日期时间

参考官网链接:https://www.elastic.co/guide/en/logstash/7.17/plugins-filters-date.html

[root@ELK102 ~]# cat config/06-file-filter-es.conf
input { 
  file {
    start_position => "beginning"
    path => ["/var/log/nginx/access.log"]
  }
}  

filter {
  grok {
    match => "%{COMMONAPACHELOG}"
  }
}

output { 
  elasticsearch{
    hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19300"]
    index => "koten-nginx-access-%{+yyyy.MM.dd}"
  }
  stdout {
    codec => rubydebug 
  } 
}
[root@ELK102 ~]# logstash -rf config/06-file-filter-es.conf

由于在kinbana中,若更改索引名字有日期,添加索引模式,下拉时间戳字段会显示@timestamp 

@timestamp 字段是logstash读取到日志的时间

我们可以根据该时间进行筛选,但是该时间并不是日志的时间,有些时候我们想针对日志中的时间筛选,就需要date插件来定义日志中的时间

我们根据官网提供的时间符号来定义自己的时间格式

[root@ELK102 ~]# cat config/07-file-filter-es.conf
input { 
  file {
    start_position => "beginning"
    path => ["/var/log/nginx/access.log"]
  }
}  

filter {
  grok {
    match => {
      "message" => "%{COMMONAPACHELOG}"
    }
  }
  date {
    match => [ 
      # "28/May/2023:16:46:15 +0800"
      "timestamp", "dd/MMM/yyyy:HH:mm:ss Z"
    ]

    target => "koten-timestamp"
  }
}

output { 
  elasticsearch{
    hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19300"]
    index => "koten-nginx-access-%{+yyyy.MM.dd}"
  }
  stdout {
    codec => rubydebug 
  } 
}

 删除之前加入的索引和索引模式,删除logstash记录的添加收集记录,运行新的配置文件

[root@ELK102 ~]# rm -rf /usr/share/logstash/data/plugins/inputs/file/.sincedb_*
[root@ELK102 ~]# logstash -rf config/07-file-filter-es.conf
......
{
    "koten-timestamp" => 2023-05-29T03:22:53.000Z,        #格林威治时间
              "bytes" => "0",
               "verb" => "GET",
          "timestamp" => "29/May/2023:11:22:53 +0800",    #日志中的时间
         "@timestamp" => 2023-05-29T12:47:30.415Z,        #logstash读取到日志的时间
               "path" => "/var/log/nginx/access.log",
               "host" => "ELK102",
              "ident" => "-",
           "response" => "304",
           "@version" => "1",
        "httpversion" => "1.1",
            "request" => "/",
               "auth" => "-",
            "message" => "10.0.0.1 - - [29/May/2023:11:22:53 +0800] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.50\" \"-\"",
           "clientip" => "10.0.0.1"
}

此时timestamp字段已经由text字段,子字段是keyword字段转换成了date字段

选择自己自定义的日志中的时间戳格式 

 观察字段发现右上角筛选日期变成了按照日志时间进行筛选

四、useragent插件

参考官网链接:https://www.elastic.co/guide/en/logstash/7.17/plugins-filters-useragent.html

分析"/tmp/nginx.log"日志,采集后写入ES,并分析2011~2021的访问量pv,设备类型

1、将一些nginx记录提前准备好,放到/tmp/下,命名为nginx.log

[root@ELK102 ~]# ll -h /tmp/nginx.log 
-rw-r--r-- 1 root root 63M May 29 20:57 /tmp/nginx.log
[root@ELK102 ~]# wc -l /tmp/nginx.log
294549 /tmp/nginx.log
[root@ELK102 ~]# head -1 /tmp/nginx.log
54.94.14.30 - - [15/Sep/2010:02:16:14 +0800] "POST /zhibo.html HTTP/1.1" 200 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" "-"

2、清空logstash缓存,方便其自动添加

[root@ELK102 ~]# rm -rf /usr/share/logstash/data/plugins/inputs/file/.since*

3、编写配置文件采集日志,并按照指定格式加入ES索引

[root@ELK102 ~]# cat config/08-file-filter-es.conf 
input { 
  file {
    start_position => "beginning"
    path => ["/tmp/nginx.log"]
  }
}  

filter {
  grok { #分析文本并解析提取需要的字段
    match => { #匹配文本字段,可以引用内置的正则变量
      "message" => "%{COMMONAPACHELOG}"
    }
  }
  date { #解析日期的字段
    match => [ #对时间进行格式化匹配并转换成ES的date字段
      # "28/May/2023:16:46:15 +0800"
      "timestamp", "dd/MMM/yyyy:HH:mm:ss Z"
    ]
    #将转换后的结果存储在指定字段,若不指定,则默认覆盖@timestamp字段
    target => "koten-timestamp"
  }
  # 分析客户端设备类型
  useragent {
      # 指定要分析客户端的字段
      source => "message"
      # 指定将分析的结果放在哪个字段中,若不指定,则放在顶级字段中。
      target => "koten-agent"
  }
}

output { 
  elasticsearch{
    hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19300"]
    index => "koten-nginx-access-%{+yyyy.MM.dd}"
  }
  #stdout {        #数据量过大,挨个输出到屏幕上浪费时间
  #  codec => rubydebug 
  #} 
}

4、运行logstash

[root@ELK102 ~]# logstash -rf config/08-file-filter-es.conf 

这些都是useragent插件生成的设备信息的字段

五、geoip插件

参考官网链接:https://www.elastic.co/guide/en/logstash/7.17/plugins-filters-geoip.html

写入地理位置测试数据到ES中,并在kibana中生成地图

1、在postman中创建索引并指定location字段

将location字段定义成geo_point类型

PUT http://10.0.0.101:19200/koten-map

{
  "mappings": {
    "properties": {
      "location": { 
        "type": "geo_point"
      }
    }
  }
}

2、写入一些测试数据

POST http://10.0.0.101:19200/_bulk

{ "create" : { "_index" : "koten-map" } }
{ "location": { "lat": 24,"lon": 121 }}
{ "create" : { "_index" : "koten-map" } }
{ "location": { "lat": 36.61,"lon": 114.488 }}
{ "create" : { "_index" : "koten-map" } }
{ "location": { "lat": 39.914,"lon": 116.386 }}

3、kibana添加地图

创建索引模式--->菜单栏 ---> Maps ---> 添加图层 ---> 文档 ---> 选择已添加的索引

 

 

添加图形好后可以做很多图形设置,配置好后点击保存并关闭

我们可以在地图上看到我们的数据所在的大概位置,数据根据经纬度显示在地图上,可以拖拽地图,可以进行缩放

六、geoip插件分析Nginx日志

提取nginx.log中的公网ip,由logstash转成经纬度,写入ES中并在kibana中以地图形式显示

(如果跟着我的操作做的话,请先看第6步)

1、删除先前生成的索引,并删除logstash的提交记录

[root@ELK102 ~]# rm -rf /usr/share/logstash/data/plugins/inputs/file/.since*

2、编辑配置文件提交我们的nginx.log数据

[root@ELK102 ~]# cat config/09-file-filter-es.conf
input { 
  file {
    start_position => "beginning"
    path => ["/tmp/nginx.log"]
  }
}  

filter {
  grok { #分析文本并解析提取需要的字段
    match => { #匹配文本字段,可以引用内置的正则变量
      "message" => "%{COMMONAPACHELOG}"
    }
  }
  date { #解析日期的字段
    match => [ #对时间进行格式化匹配并转换成ES的date字段
      # "28/May/2023:16:46:15 +0800"
      "timestamp", "dd/MMM/yyyy:HH:mm:ss Z"
    ]
    #将转换后的结果存储在指定字段,若不指定,则默认覆盖@timestamp字段
    target => "koten-timestamp"
  }
  # 分析客户端设备类型
  useragent {
      # 指定要分析客户端的字段
      source => "message"
      # 指定将分析的结果放在哪个字段中,若不指定,则放在顶级字段中。
      target => "koten-agent"
  }
  #基于IP地址分析地理位置
  geoip{
    #指定基于哪个字段分析IP地理位置 
    source => "clientip"
  }
}

output { 
  elasticsearch{
    hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19300"]
    index => "koten-nginx-access-%{+yyyy.MM.dd}"
  }
 # stdout {
 #   codec => rubydebug 
 # } 
}

3、执行logstash,写入ES数据

[root@ELK102 ~]# logstash -rf config/09-file-filter-es.conf

4、创建索引模式,创建地图图层,发现索引模式不包含任何地理空间字段

5、原因是字段类型并没有修改,解决办法是创建索引模板

location下的经纬度默认是浮点数

 创建索引模板

6、添加模板后重复上面删除索引,运行logstash的操作,创建索引模式,再次创建地图图层,成功将数据显示在地图上(因为索引映射一旦确定不能更改,只能删除索引重新添加)

添加好图层后可以看到地图上显示了我们索引中文档的数据

右上角可以保存地图 

保存并添加到库,也可以保存到仪表板,我还没有创建就先不添加了,以后想看可以在库中随时调用出来。

七、mutate插件

参考官网链接:https://www.elastic.co/guide/en/logstash/7.17/plugins-filters-mutate.html

当我们的日志中的字段是按照指定字符分割开来时,就需要用到该插件了,mutate插件适合对字段的信息进行分割,通过分割可以很方便的定义添加字段,虽然用grok写正则表达式也可以实现匹配字段,但是写很多表达式还是很麻烦的。

1、编写生成日志的脚本,模拟公司产品的日志

cat > generate_log.py  <<EOF
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import datetime
import random
import logging
import time
import sys

LOG_FORMAT = "%(levelname)s %(asctime)s [com.koten.%(module)s] - %(message)s "
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"

# 配置root的logging.Logger实例的基本配置
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT, datefmt=DATE_FORMAT, filename=sys.argv[1]
, filemode='a',)
actions = ["浏览页面", "评论商品", "加入收藏", "加入购物车", "提交订单", "使用优惠券", "领取优惠券",
 "搜索", "查看订单", "付款", "清空购物车"]

while True:
    time.sleep(random.randint(1, 5))
    user_id = random.randint(1, 10000)
    # 对生成的浮点数保留2位有效数字.
    price = round(random.uniform(15000, 30000),2)
    action = random.choice(actions)
    svip = random.choice([0,1])
    logging.info("DAU|{0}|{1}|{2}|{3}".format(user_id, action,svip,price))
EOF

2、生成测试的日志

[root@ELK102 ~]# python generate_log.py  /tmp/app.log
[root@ELK102 ~]# cat /tmp/app.log 
INFO 2023-05-29 23:34:52 [com.koten.generate_log] - DAU|3849|提交订单|1|15990.11 
INFO 2023-05-29 23:34:57 [com.koten.generate_log] - DAU|189|查看订单|0|26263.25 
INFO 2023-05-29 23:34:58 [com.koten.generate_log] - DAU|8444|领取优惠券|0|25803.03 
INFO 2023-05-29 23:35:03 [com.koten.generate_log] - DAU|5440|搜索|0|20433.35 
INFO 2023-05-29 23:35:08 [com.koten.generate_log] - DAU|2913|提交订单|1|22605.35 
INFO 2023-05-29 23:35:11 [com.koten.generate_log] - DAU|3708|提交订单|1|28590.17 
INFO 2023-05-29 23:35:15 [com.koten.generate_log] - DAU|9296|使用优惠券|0|16057.25 
INFO 2023-05-29 23:35:20 [com.koten.generate_log] - DAU|6150|评论商品|1|20976.35 
INFO 2023-05-29 23:35:23 [com.koten.generate_log] - DAU|8145|提交订单|0|15477.72 
INFO 2023-05-29 23:35:24 [com.koten.generate_log] - DAU|689|搜索|1|24395.35 
INFO 2023-05-29 23:35:28 [com.koten.generate_log] - DAU|1439|领取优惠券|1|15574.72 
......

3、使用mutate组件分析日志,编辑配置文件

[root@ELK102 ~]# cat config/10-file-filter-es.conf
input { 
  file {
    start_position => "beginning"
    path => ["/tmp/app.log"]
  }
}  

filter {
   # 对文本数据进行处理
   mutate {
      # 对message字段按照"|"进行切割
      split => { "message" => "|" }
   }
  
   mutate {
     # 添加字段
     add_field => {
        user_id => "%{[message][1]}"
        action => "%{[message][2]}"
        svip => "%{[message][3]}"
        price => "%{[message][4]}"
     }
   }
  
   mutate {
     # 进行数据类型转换,将指定字段换成为期望的数据类型
     convert => {
       "user_id" => "integer"
       "svip" => "boolean"
       "price" => "float"
     }
   }

   mutate {
     # 对字段进行重命名
     rename => { "path" => "filepath" }
   }

   mutate {
     # 移除指定的字段
     remove_field => [ "@version","message" ]
   }
}

output { 
  elasticsearch{
    hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19300"]
    index => "koten-nginx-access-%{+yyyy.MM.dd}"
  }
 # stdout {
 #   codec => rubydebug 
 # } 
}

4、启用logstash,观察屏幕输出的日志是否按照自定义字段输出

[root@ELK102 ~]# rm -rf /usr/share/logstash/data/plugins/inputs/file/.sincedb_*
[root@ELK102 ~]# logstash -rf config/10-file-filter-es.conf 

5、kibana查看数据并创建可视化

创建数据图表:菜单栏 ---> Visualize library ---> 创建可视化 ---> Lens ---> 根据字段选择即可。

 

 

 

创建聚合图形:菜单栏 ---> Visualize library ---> 创建可视化 --->  基于聚合  ---> 指标(其他同理) ---> 选择索引  

 可以修改标签,更新显示,同样右上角可以保存

 创建仪表板:Overview--->仪表板--->创建新的仪表板--->从库中添加--->保存仪表板

可以添加库中的图形 

右上角保存仪表板

 下次再打开Overview就显示了,可以打开直接看

八、if多分支语句

if多分支语句与--path.data一样,是多个输入多个输出的一种方式

1、准备读入文件

[root@ELK102 ~]# cat /tmp/haha.log
welcome to kotenedu linux, 2023
[root@ELK102 ~]# cat /tmp/app.log 
INFO 2023-05-29 23:34:52 [com.koten.generate_log] - DAU|3849|提交订单|1|15990.11 
INFO 2023-05-29 23:34:57 [com.koten.generate_log] - DAU|189|查看订单|0|26263.25 
INFO 2023-05-29 23:34:58 [com.koten.generate_log] - DAU|8444|领取优惠券|0|25803.03 
INFO 2023-05-29 23:35:03 [com.koten.generate_log] - DAU|5440|搜索|0|20433.35 
INFO 2023-05-29 23:35:08 [com.koten.generate_log] - DAU|2913|提交订单|1|22605.35 
INFO 2023-05-29 23:35:11 [com.koten.generate_log] - DAU|3708|提交订单|1|28590.17 
INFO 2023-05-29 23:35:15 [com.koten.generate_log] - DAU|9296|使用优惠券|0|16057.25 
INFO 2023-05-29 23:35:20 [com.koten.generate_log] - DAU|6150|评论商品|1|20976.35 
INFO 2023-05-29 23:35:23 [com.koten.generate_log] - DAU|8145|提交订单|0|15477.72 
INFO 2023-05-29 23:35:24 [com.koten.generate_log] - DAU|689|搜索|1|24395.35 
INFO 2023-05-29 23:35:28 [com.koten.generate_log] - DAU|1439|领取优惠券|1|15574.72 
......

2、准备正则表达式

[root@ELK102 ~]# cat config/koten-patterns/koten-patterns
SCHOOL [a-z]{8}
SUBJECT [a-z]{5}
YEAR [\d]{4}

3、编辑配置文件

[root@ELK102 ~]# cat config/11-file-filter-es.conf
input { 
  file {
    start_position => "beginning"
    path => ["/tmp/haha.log"]
    type => "haha"
  }

  file {
    start_position => "beginning"
    path => ["/tmp/app.log"]
    type => "app"
  }
}  


filter {
   if [type] == "haha" {
      grok {
        patterns_dir => ["./koten-patterns/"]
        match => {
          "message" => "welcome to %{SCHOOL:school} %{SUBJECT:subject}, %{YEAR:year}"
        }
      }

   } else if [type] == "app" {
       mutate {
          split => { "message" => "|" }
       }

       mutate {
         add_field => {
            user_id => "%{[message][1]}"
            action => "%{[message][2]}"
            svip => "%{[message][3]}"
            price => "%{[message][4]}"
         }
       }

       mutate {
         convert => {
           "user_id" => "integer"
           "svip" => "boolean"
           "price" => "float"
         }
       }

       mutate {
         rename => { "path" => "filepath" }
       }

       mutate {
         remove_field => [ "@version","message" ]
       }

  }
}



output { 
  if [type] == "haha" {
    elasticsearch {
      hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19200"]
      index => "koten-if-haha-%{+yyyy.MM.dd}"
    } 
  } else if [type] == "app" {
    elasticsearch {
      hosts => ["10.0.0.101:19200","10.0.0.102:19200","10.0.0.103:19200"]
      index => "koten-if-app-%{+yyyy.MM.dd}"
    } 
  }

  stdout {
    codec => rubydebug 
  } 
}

4、运行logstash,可以观察到两者输入输出的区别,更名的字段等等

[root@ELK102 ~]# rm -rf /usr/share/logstash/data/plugins/inputs/file/.sinced*
[root@ELK102 ~]# logstash -rf config/11-file-filter-es.conf
......
{
          "type" => "app",
      "filepath" => "/tmp/app.log",
       "user_id" => 9389,
          "svip" => false,
          "host" => "ELK102",
    "@timestamp" => 2023-05-29T16:31:25.353Z,
         "price" => 26972.71,
        "action" => "付款"
}
{
          "path" => "/tmp/haha.log",
          "type" => "haha",
       "subject" => "linux",
      "@version" => "1",
          "host" => "ELK102",
          "year" => "2023",
    "@timestamp" => 2023-05-29T16:31:25.240Z,
       "message" => "welcome to kotenedu linux, 2023",
        "school" => "kotenedu"
}
......

Logstash常用filter插件总结

1、grok:正则匹配任意文本

2、date:处理时间字段

3、user_agent:分析客户端设备

4、geoip:分析客户端IP地理位置

5、mutate:对字符串文本进行处理,转换,字母大小写,切分,重命名,添加字段,删除字段

运行多个输入和输出的方案:

多实例:需要单独指定数据路径,--data.path

if分支语句:

if [type] == "xxx" {

} else if [type] == "xxx" {

} else {

}

pipline:logstash运行时默认就有一个main pipline


我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!

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

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

相关文章

信号分析仪-4024CA频谱分析仪 频率范围9kHz~9GHz

01 4024CA频谱分析仪 产品综述&#xff1a; 4024CA频谱分析仪是一款专为外场测试而设计的大宽带手持式实时频谱分析仪&#xff0c;最大实时分析带宽达到120MHz&#xff0c;具有实时频谱分析、5G NR解调分析、LTE FDD/TDD解调分析、GSM/EDGE解调分析、定向分析等多种测量功能…

英伟达“阉割版”AI芯片遇阻,推迟至明年发布 | 百能云芯

近日&#xff0c;英伟达&#xff08;Nvidia&#xff09;为遵守美国出口规定而推迟在中国市场推出的新款人工智能&#xff08;AI&#xff09;芯片引起了业界广泛关注。 据路透社报道&#xff0c;两位消息人士透露&#xff0c;该芯片被命名为H20&#xff0c;是英伟达为遵守美国最…

JavaEE(SpringMVC)期末复习(选择+填空+解答)

文章目录 JavaEE期末复习一、单选题&#xff1a;二、多选题三、填空题四、解答 JavaEE期末复习 一、单选题&#xff1a; 1.Spring的核⼼技术是&#xff08; A &#xff09;&#xff1f; A依赖注入 B.JdbcTmplate C.声明式事务 D.资源访问 Spring的核心技术包括依赖注入&#x…

从零带你底层实现unordered_map (2)

&#x1f4af; 博客内容&#xff1a;从零带你实现unordered_map &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准C后端工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家…

springboot云HIS医院信息综合管理平台源码

满足基层医院机构各类业务需要的健康云HIS系统。该系统能帮助基层医院机构完成日常各类业务&#xff0c;提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生站和护士站等一系列常规功能&#xff0c;能与公卫、PACS等各类外部系统融合&#xff0c;实现多…

服务器主机安全如何保障

随着互联网的快速发展&#xff0c;服务器主机安全问题日益凸显。服务器主机是网络世界中的核心&#xff0c;其安全性关乎着整个网络系统的稳定性和可靠性。 当前&#xff0c;服务器主机面临着多种安全威胁。其中&#xff0c;网络攻击是最为常见的一种。网络攻击者利用各种手段…

Java核心知识点整理大全20-笔记

目录 17. 设计模式 17.1.1. 设计原则 17.1.24. 解释器模式 18. 负载均衡 18.1.1.1. 四层负载均衡&#xff08;目标地址和端口交换&#xff09; 18.1.1.2. 七层负载均衡&#xff08;内容交换&#xff09; 18.1.2. 负载均衡算法/策略 18.1.2.1. 轮循均衡&#xff08;Roun…

【doccano】文本标注工具——安装运行教程

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【doccano】文本标注工具 doccano简介安装doccano1. 创建并激活虚拟环境2. 安装doccano 运行Doccano访问Doccano doccano简介 doccano是一个开源的文本注释工具。它为文本分类、序列标记和序列到序列任务提供注释…

人工智能应用:文本分类的技术突破与实战指导

随着信息爆炸式增长&#xff0c;处理大量文本数据的需求也日益迫切。文本分类作为一种常见的人工智能应用&#xff0c;通过将文本数据分到不同的预定义类别中&#xff0c;帮助解决信息分类和处理的问题。本文将探讨文本分类的技术突破以及实战指导&#xff0c;帮助读者了解其原…

spring-boot集成mybatis-generator

通用 Mapper 在 1.0.0 版本的时候增加了 MyBatis Generator (以下简称 MBG) 插件&#xff0c;使用该插件可以很方便的生成实体类、Mapper 接口以及对应的 XML 文件。 下面介绍了 mybatis-generator 在 spring-boot 中的使用过程 一、引入pom依赖 <dependencies><de…

IE工业工程不可不知的高效工具 – 视与视ECRS生产现场动作分析与改善软件

生产现场的作业效率如何改善&#xff1f; 如何有效优化一线生产者的动作&#xff0c;从而提升作业效率&#xff1f; 新进员工如何进行规范化的作业培训&#xff1f; 如何对班组、个人的生产效率进行定量分析与优化&#xff1f; 山积表、作业指导书、标准作业组合表、生产平…

2.3基于springboot养老院管理系统

2.3基于springboot养老院管理系统 成品项目已经更新&#xff01;同学们可以打开链接查看&#xff01;需要定做的及时联系我&#xff01;专业团队定做&#xff01;全程包售后&#xff01; 2000套项目视频链接&#xff1a;https://pan.baidu.com/s/1N4L3zMQ9nNm8nvEVfIR2pg?pwd…

Flutter 桌面应用开发之读写Windows注册表

文章目录 需求来源Windows查询Windows版本号方法1. 如何查看Windows版本号2. Windows开发如何通过代码查询Windows版本号(1) 使用C#代码&#xff1a;(2) 使用VB.NET代码 3.通过注册表查看Windows版本信息 Flutter查询Windows版本号方法依赖库支持平台实现步骤1. 在pubspec.yaml…

来自2023 TM Forum 数字领导力中国峰会的邀请函

峰会介绍 2023数字领导力中国峰会由tmforum和亚信科技联合主办。 数据驱动创新&#xff0c;数字塑造未来&#xff01;2023数字领导力中国峰会&#xff0c;立足技术和商业视角&#xff0c;聚焦讨论各行业如何依托数据治理、IT和网络转型&#xff0c;实现跨越式增长。 这里&am…

电子信息工程系用STM32做个毕业项目,有什么好的推荐?

电子信息工程系用STM32做个毕业项目&#xff0c;有什么好的推荐&#xff1f; 我推荐三个项目&#xff0c;但是个人觉得&#xff0c;首先看你自己喜不喜欢这个专业&#xff0c;因为电子工程对于我推荐的这几个项目实际是最基本的&#xff0c;同时推荐二和推荐三都是有相当的难度…

健全隧道健康监测,保障隧道安全管理

隧道工程事故的严重性不容忽视。四川隧道事故再次凸显了隧道施工的危险性&#xff0c;以及加强隧道安全监管的必要性。隧道工程事故不仅会给受害人带来巨大的痛苦和家庭悲剧&#xff0c;也会对整个社会产生严重的负面影响。因此&#xff0c;如何有效地降低隧道工程事故的发生率…

解析和存储优化的批量爬虫采集策略

如果你正在进行批量爬虫采集工作&#xff0c;并且想要优化解析和存储过程&#xff0c;提高采集效率和稳定性&#xff0c;那么本文将为你介绍一些实用的策略和技巧。解析和存储是批量爬虫采集中不可忽视的重要环节&#xff0c;其效率和质量对整个采集系统的性能至关重要。在下面…

DC电源模块有哪些常见故障?怎么解决这些问题?

DC-DC电源模块的作用是将输入电压转换为所需的输出电压&#xff0c;广泛应用于电子产品、汽车电子、医疗设备、通信系统等领域。但是在使用过程中DC电源模块会出现一些故障和问题&#xff0c;影响电源模块和其它电路器件的性能。因此&#xff0c;纳米软件将为大家介绍常见的DC-…

微信支付和微信红包设计用例

微信支付 功能 扫二维码 1.第一次扫描付钱二维码时可以得到相机权限&#xff0c;进入付钱界面 2.第一次扫描付钱二维码时可以拒绝相机权限&#xff0c;退回聊天界面 3.扫一扫可以扫描收钱的二维码 4.扫描出来的信息与收钱人信息相符 5.输入框只能输入数字 6.一次能支付的…

java对象 转换成json字符串 工具类 jackson

jackson概述 Jackson 是一个用于处理 JSON 数据的 Java 库&#xff0c;由 FasterXML 公司开发和维护。它提供了一组功能强大的 API&#xff0c;用于在 Java 对象和 JSON 数据之间进行高效的序列化&#xff08;将对象转换为 JSON 格式&#xff09;和反序列化&#xff08;将 JSO…