aux_logid/
lib.rs

1use std::net::{IpAddr, Ipv6Addr, UdpSocket};
2
3use chrono::Utc;
4use lazy_static::lazy_static;
5
6const VERSION: &'static str = "01";
7
8lazy_static! {
9    static ref FORMAT_IP: String = {
10        let v6 = match local_ip() {
11            Some(IpAddr::V4(v4)) => v4.to_ipv6_mapped(),
12            Some(IpAddr::V6(v6)) => v6,
13            None => Ipv6Addr::from(0),
14        };
15        format!("{:032x}", u128::from(v6))
16    };
17}
18
19/// 生成一个用于追踪作用的 log id
20/// 格式: 2 位版本号 + 13 位时间戳 + 32 位 ip + 6 位十六进制随机数 = 53 位
21pub fn gen_log_id() -> String {
22    let mut id = String::new();
23    id.push_str(VERSION);
24    id.push_str(&Utc::now().timestamp_millis().to_string());
25    id.push_str(&FORMAT_IP);
26
27    use rand::Rng;
28    let rand_hex = format!("{:06x}", rand::thread_rng().gen_range(0..=0xffffff));
29    id.push_str(&rand_hex);
30    id
31}
32
33/// 获得本地 ip,并不会真的发起请求,使用 udp 也不会有握手请求
34fn local_ip() -> Option<IpAddr> {
35    let socket = UdpSocket::bind("0.0.0.0:0").ok()?;
36    socket.connect("8.8.8.8:80").ok()?;
37    socket.local_addr().map(|addr| addr.ip()).ok()
38}
39
40#[test]
41fn test_get_local_ip() {
42    println!("{:?}", local_ip());
43}
44
45#[test]
46fn test_gen_log_id() {
47    println!("{}", gen_log_id());
48}