feat: 添加日志功能
This commit is contained in:
parent
5a0f888000
commit
ee2e8dd1c6
@ -31,3 +31,5 @@ serde = { version = "1.0.215", features = ["derive"] }
|
||||
futures = "0.3.31"
|
||||
mime_guess = "2.0.5"
|
||||
actix-files = "0.6.6"
|
||||
simplelog = "0.12.2"
|
||||
log = "0.4.22"
|
67
src/logger.rs
Normal file
67
src/logger.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use log::{debug, error, info, warn, LevelFilter};
|
||||
use simplelog::*;
|
||||
use std::fs::{create_dir_all, File, OpenOptions};
|
||||
use std::path::Path;
|
||||
|
||||
const MAX_LOG_SIZE: u64 = 50 * 1024 * 1024;
|
||||
const LOG_FILE_PATH: &str = "data/rust.log";
|
||||
|
||||
pub fn init_logger() {
|
||||
let mut builder = ConfigBuilder::new();
|
||||
builder.set_time_offset_to_local().unwrap();
|
||||
let config = builder.build();
|
||||
|
||||
// 获取文件的目录路径
|
||||
let dir = Path::new(LOG_FILE_PATH).parent().unwrap();
|
||||
|
||||
// 检查并创建目录
|
||||
if !dir.exists() {
|
||||
create_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
let file = OpenOptions::new()
|
||||
.write(true)
|
||||
.append(true)
|
||||
.create(true)
|
||||
.open(LOG_FILE_PATH).unwrap();
|
||||
|
||||
CombinedLogger::init(
|
||||
vec![
|
||||
TermLogger::new(LevelFilter::Info, config.clone(), TerminalMode::Mixed, ColorChoice::Auto),
|
||||
WriteLogger::new(LevelFilter::Info, config.clone(), file),
|
||||
]
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
// 检查文件大小并清空文件(如果超出限制)
|
||||
fn check_and_clear_log_file() {
|
||||
let metadata = std::fs::metadata(LOG_FILE_PATH).unwrap();
|
||||
if metadata.len() > MAX_LOG_SIZE {
|
||||
// 清空文件
|
||||
File::create(LOG_FILE_PATH).expect(&format!("Can't re-create file {}", LOG_FILE_PATH));
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn debug(message: &str) {
|
||||
check_and_clear_log_file();
|
||||
debug!("{}", message);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn info(message: &str) {
|
||||
check_and_clear_log_file();
|
||||
info!("{}", message);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn warn(message: &str) {
|
||||
check_and_clear_log_file();
|
||||
warn!("{}", message);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn error(message: &str) {
|
||||
check_and_clear_log_file();
|
||||
error!("{}", message);
|
||||
}
|
42
src/main.rs
42
src/main.rs
@ -1,6 +1,7 @@
|
||||
mod encryption;
|
||||
mod router;
|
||||
mod sql;
|
||||
mod logger;
|
||||
|
||||
use actix_web::{
|
||||
rt,
|
||||
@ -42,7 +43,7 @@ pub struct Args {
|
||||
#[arg(short, long, default_value_t = 8000, help = "Assets port to listen on")]
|
||||
asset_port: u16,
|
||||
|
||||
#[arg(long, default_value = "./", help = "Path to store database files")]
|
||||
#[arg(long, default_value = "./data/", help = "Path to store database files")]
|
||||
path: String,
|
||||
|
||||
#[arg(long, default_value = "./asset/", help = "Path to store database files")]
|
||||
@ -110,43 +111,45 @@ async fn run_server(in_thread: bool) -> std::io::Result<()> {
|
||||
let asset_port = args.asset_port;
|
||||
|
||||
if args.purge {
|
||||
println!("Purging accounts...");
|
||||
let ct = crate::router::userdata::purge_accounts();
|
||||
println!("Purged {} accounts", ct);
|
||||
logger::debug("Purging accounts...");
|
||||
let ct = router::userdata::purge_accounts();
|
||||
logger::warn(&format!("Purged {} accounts", ct));
|
||||
}
|
||||
|
||||
let webui_server = HttpServer::new(|| App::new()
|
||||
let webui_server = HttpServer::new(|| {
|
||||
App::new()
|
||||
.wrap_fn(|req, srv| {
|
||||
println!("WebUI Request: {}", req.path());
|
||||
logger::info(&format!("WebUI Request: {}", req.path())); // 使用日志记录
|
||||
srv.call(req)
|
||||
})
|
||||
.app_data(web::PayloadConfig::default().limit(1024 * 1024 * 25))
|
||||
.service(css)
|
||||
.service(js)
|
||||
.default_service(web::route().to(router::request))
|
||||
).bind(("0.0.0.0", port))?.run();
|
||||
}).bind(("0.0.0.0", port))?.run();
|
||||
|
||||
println!("WebUI Server started: http://0.0.0.0:{}", port);
|
||||
println!("Database path is set to {}", args.path);
|
||||
println!("Sif1 transfer requests will attempt to contact NPPS4 at {}", args.npps4);
|
||||
logger::info(&format!("WebUI Server started: http://0.0.0.0:{}", port));
|
||||
logger::info(&format!("Database path is set to {}", args.path));
|
||||
logger::debug(&format!("Sif1 transfer requests will attempt to contact NPPS4 at {}", args.npps4));
|
||||
|
||||
let mut asset_server: Option<Server> = None;
|
||||
if enable_asset_server {
|
||||
asset_server = Some(HttpServer::new(|| App::new()
|
||||
asset_server = Some(HttpServer::new(|| {
|
||||
App::new()
|
||||
.wrap_fn(|req, srv| {
|
||||
println!("Assets Request: {}", req.path());
|
||||
logger::info(&format!("Assets Request: {}", req.path()));
|
||||
srv.call(req)
|
||||
})
|
||||
.app_data(web::PayloadConfig::default().limit(1024 * 1024 * 1024))
|
||||
.default_service(web::route().to(router::asset_request))
|
||||
).bind(("0.0.0.0", asset_port))?.run());
|
||||
}).bind(("0.0.0.0", asset_port))?.run());
|
||||
|
||||
println!("Assets Server started: http://0.0.0.0:{}", asset_port);
|
||||
println!("Assets path is set to {}", args.asset_path);
|
||||
logger::info(&format!("Assets Server started: http://0.0.0.0:{}", asset_port));
|
||||
logger::info(&format!("Assets path is set to {}", args.asset_path));
|
||||
}
|
||||
|
||||
if args.https {
|
||||
println!("Note: gree is set to https mode. http requests will fail on jp clients.");
|
||||
logger::warn("Note: gree is set to https mode. http requests will fail on jp clients.");
|
||||
}
|
||||
|
||||
if in_thread {
|
||||
@ -161,13 +164,13 @@ async fn run_server(in_thread: bool) -> std::io::Result<()> {
|
||||
}
|
||||
|
||||
while get_running().await {
|
||||
actix_web::rt::time::sleep(Duration::from_millis(100)).await;
|
||||
rt::time::sleep(Duration::from_millis(100)).await;
|
||||
}
|
||||
handle.stop(false).await;
|
||||
if handle2.is_some() {
|
||||
handle2.unwrap().stop(false).await;
|
||||
}
|
||||
println!("Stopped");
|
||||
logger::info("Stopped");
|
||||
return Ok(());
|
||||
}
|
||||
if asset_server.is_some() {
|
||||
@ -181,10 +184,11 @@ async fn run_server(in_thread: bool) -> std::io::Result<()> {
|
||||
#[actix_web::main]
|
||||
async fn stop_server() {
|
||||
set_running(false).await;
|
||||
println!("Stopping");
|
||||
logger::error("Stopping");
|
||||
}
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
logger::init_logger();
|
||||
run_server(false)
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,13 @@ pub mod event_ranking;
|
||||
|
||||
use actix_web::{HttpResponse, HttpRequest, http::header::HeaderValue, http::header::HeaderMap, Responder};
|
||||
use json::{JsonValue, object};
|
||||
use crate::encryption;
|
||||
use crate::{encryption, logger};
|
||||
|
||||
fn unhandled(req: HttpRequest, body: String) -> Option<JsonValue> {
|
||||
if body != String::new() {
|
||||
println!("{}", encryption::decrypt_packet(&body).unwrap_or(body));
|
||||
logger::error(&format!("{}", encryption::decrypt_packet(&body).unwrap_or(body)));
|
||||
}
|
||||
println!("Unhandled request: {}", req.path());
|
||||
logger::error(&format!("Unhandled request: {}", req.path()));
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use json::{object, array, JsonValue};
|
||||
use actix_web::{HttpRequest};
|
||||
|
||||
use crate::router::{global, items, userdata, databases};
|
||||
use crate::encryption;
|
||||
use crate::{encryption, logger};
|
||||
|
||||
pub fn add_chat(id: i64, num: i64, chats: &mut JsonValue) -> bool {
|
||||
for data in chats.members() {
|
||||
@ -23,7 +23,7 @@ pub fn add_chat(id: i64, num: i64, chats: &mut JsonValue) -> bool {
|
||||
pub fn add_chat_from_chapter_id(chapter_id: i64, chats: &mut JsonValue) -> bool {
|
||||
let chapter = &databases::CHAPTERS_MASTER[chapter_id.to_string()];
|
||||
if chapter.is_empty() {
|
||||
println!("Attempted to give unknown chapter id {}", chapter_id);
|
||||
logger::info(&format!("Attempted to give unknown chapter id {}", chapter_id));
|
||||
return false;
|
||||
}
|
||||
add_chat(chapter["masterChatId"].as_i64().unwrap(), chapter["roomId"].as_i64().unwrap(), chats)
|
||||
|
@ -1,12 +1,12 @@
|
||||
use json::{JsonValue, object};
|
||||
use actix_web::{HttpRequest};
|
||||
|
||||
use crate::encryption;
|
||||
use crate::{encryption, logger};
|
||||
|
||||
pub fn error(_req: HttpRequest, body: String) -> Option<JsonValue> {
|
||||
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
|
||||
|
||||
println!("client error: {}", body["code"]);
|
||||
logger::error(&format!("client error: {}", body["code"]));
|
||||
|
||||
Some(object!{})
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use json::{array, object, JsonValue};
|
||||
use rand::Rng;
|
||||
use actix_web::{HttpRequest, http::header::{HeaderMap, HeaderValue}};
|
||||
use crate::encryption;
|
||||
use crate::{encryption, logger};
|
||||
|
||||
use crate::router::{userdata, global, databases};
|
||||
|
||||
@ -113,7 +113,7 @@ pub fn use_item(item: &JsonValue, multiplier: i64, user: &mut JsonValue) {
|
||||
} else if item["consumeType"] == 4 {
|
||||
use_itemm(item["value"].as_i64().unwrap(), item["amount"].as_i64().unwrap() * multiplier, user);
|
||||
} else {
|
||||
println!("Unknown consume type {}", item["consumeType"]);
|
||||
logger::error(&format!("Unknown consume type {}", item["consumeType"]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ pub fn give_gift(data: &JsonValue, user: &mut JsonValue, missions: &mut JsonValu
|
||||
}
|
||||
return false;
|
||||
}
|
||||
println!("Redeeming reward not implemented for reward type {}", data["reward_type"]);
|
||||
logger::error(&format!("Redeeming reward not implemented for reward type {}", data["reward_type"]));
|
||||
false
|
||||
}
|
||||
pub fn give_gift_basic(ty_pe: i32, id: i64, amount: i64, user: &mut JsonValue, missions: &mut JsonValue, clear_missions: &mut JsonValue, chats: &mut JsonValue) -> bool {
|
||||
@ -279,7 +279,7 @@ pub fn get_rarity(id: i64) -> i32 {
|
||||
pub fn give_character(id: i64, user: &mut JsonValue, missions: &mut JsonValue, clear_missions: &mut JsonValue, chats: &mut JsonValue) -> bool {
|
||||
let character_rarity = get_rarity(id);
|
||||
if character_rarity == 0 {
|
||||
println!("Attempted to give user undefined card!! Card id: {}", id);
|
||||
logger::error(&format!("Attempted to give user undefined card!! Card id: {}", id));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -498,7 +498,7 @@ pub fn use_item_req(req: HttpRequest, body: String) -> Option<JsonValue> {
|
||||
if item["effectType"].as_i32().unwrap() == 1 {
|
||||
lp_modification(&mut user, item["effectValue"].as_u64().unwrap() * (amount as u64), false);
|
||||
} else {
|
||||
println!("Use item not implemented for effect type {}", item["effectType"]);
|
||||
logger::error(&format!("Use item not implemented for effect type {}", item["effectType"]));
|
||||
}
|
||||
use_item(&object!{
|
||||
value: body["id"].as_i64().unwrap(),
|
||||
|
@ -1,12 +1,12 @@
|
||||
use json::{JsonValue, object};
|
||||
use actix_web::{HttpRequest, http::header::HeaderValue};
|
||||
|
||||
use crate::encryption;
|
||||
use crate::{encryption, logger};
|
||||
use crate::router::{userdata, global};
|
||||
|
||||
fn get_asset_hash(req: &HttpRequest, body: &JsonValue) -> String {
|
||||
if body["asset_version"] != global::ASSET_VERSION && body["asset_version"] != global::ASSET_VERSION_JP {
|
||||
println!("Warning! Asset version is not what was expected. (Did the app update?)");
|
||||
logger::warn("Warning! Asset version is not what was expected. (Did the app update?)");
|
||||
}
|
||||
|
||||
let blank_header = HeaderValue::from_static("");
|
||||
@ -29,7 +29,7 @@ pub fn start(req: HttpRequest, body: String) -> Option<JsonValue> {
|
||||
let body = json::parse(&encryption::decrypt_packet(&body).unwrap()).unwrap();
|
||||
let mut user = userdata::get_acc(&key);
|
||||
|
||||
println!("Signin from uid: {}", user["user"]["id"].clone());
|
||||
logger::info(&format!("Signin from uid: {}", user["user"]["id"].clone()));
|
||||
|
||||
user["user"]["last_login_time"] = global::timestamp().into();
|
||||
|
||||
|
@ -2,7 +2,7 @@ use json::{array, object, JsonValue};
|
||||
use actix_web::{HttpRequest};
|
||||
use sha1::{Sha1, Digest};
|
||||
|
||||
use crate::encryption;
|
||||
use crate::{encryption, logger};
|
||||
use crate::router::{userdata, global, items};
|
||||
use crate::include_file;
|
||||
|
||||
@ -329,7 +329,7 @@ async fn npps4_req(sha_id: String) -> Option<JsonValue> {
|
||||
host.pop();
|
||||
}
|
||||
let url = format!("{}/ewexport?sha1={}", host, sha_id);
|
||||
println!("Polling NPPS4 at {}", host);
|
||||
logger::debug(&format!("Polling NPPS4 at {}", host));
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let response = client.get(url);
|
||||
|
@ -8,7 +8,7 @@ use base64::{Engine as _, engine::general_purpose};
|
||||
use crate::router::global;
|
||||
use crate::router::items;
|
||||
use crate::sql::SQLite;
|
||||
use crate::include_file;
|
||||
use crate::{include_file, logger};
|
||||
|
||||
lazy_static! {
|
||||
static ref DATABASE: SQLite = SQLite::new("userdata.db", setup_tables);
|
||||
@ -625,7 +625,7 @@ pub fn purge_accounts() -> usize {
|
||||
)).unwrap();
|
||||
for uid in dead_uids.members() {
|
||||
let user_id = uid.as_i64().unwrap();
|
||||
println!("Removing dead UID: {}", user_id);
|
||||
logger::error(&format!("Removing dead UID: {}", user_id));
|
||||
crate::router::gree::delete_uuid(user_id);
|
||||
DATABASE.lock_and_exec("DELETE FROM userdata WHERE user_id=?1", params!(user_id));
|
||||
DATABASE.lock_and_exec("DELETE FROM userhome WHERE user_id=?1", params!(user_id));
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState, useParams, useEffect } from 'react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import './Home.css'
|
||||
import Request from '../Request.jsx'
|
||||
let bonusItems = [];
|
||||
|
Loading…
x
Reference in New Issue
Block a user