mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-06-06 13:53:54 +02:00
copy plugin sources
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "log"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
tauri.workspace = true
|
||||
serde_repr = "0.1"
|
||||
byte-unit = "4.0"
|
||||
fern = "0.6"
|
||||
log = { workspace = true, features = ["kv_unstable"] }
|
||||
time = { version = "0.3", features = ["formatting"] }
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
var d=Object.defineProperty;var e=(c,a)=>{for(var b in a)d(c,b,{get:a[b],enumerable:!0});};
|
||||
|
||||
var f={};e(f,{convertFileSrc:()=>w,invoke:()=>c$1,transformCallback:()=>s$1});function u$1(){return window.crypto.getRandomValues(new Uint32Array(1))[0]}function s$1(e,r=!1){let n=u$1(),t=`_${n}`;return Object.defineProperty(window,t,{value:o=>(r&&Reflect.deleteProperty(window,t),e==null?void 0:e(o)),writable:!1,configurable:!0}),n}async function c$1(e,r={}){return new Promise((n,t)=>{let o=s$1(i=>{n(i),Reflect.deleteProperty(window,`_${a}`);},!0),a=s$1(i=>{t(i),Reflect.deleteProperty(window,`_${o}`);},!0);window.__TAURI_IPC__({cmd:e,callback:o,error:a,...r});})}function w(e,r="asset"){let n=encodeURIComponent(e);return navigator.userAgent.includes("Windows")?`https://${r}.localhost/${n}`:`${r}://localhost/${n}`}
|
||||
|
||||
async function a(i){return c$1("tauri",i)}
|
||||
|
||||
var W={};e(W,{TauriEvent:()=>c,emit:()=>D,listen:()=>E,once:()=>_});async function s(n,t){return a({__tauriModule:"Event",message:{cmd:"unlisten",event:n,eventId:t}})}async function m(n,t,i){await a({__tauriModule:"Event",message:{cmd:"emit",event:n,windowLabel:t,payload:i}});}async function o(n,t,i){return a({__tauriModule:"Event",message:{cmd:"listen",event:n,windowLabel:t,handler:s$1(i)}}).then(r=>async()=>s(n,r))}async function u(n,t,i){return o(n,t,r=>{i(r),s(n,r.id).catch(()=>{});})}var c=(e=>(e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_FILE_DROP="tauri://file-drop",e.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",e.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",e.MENU="tauri://menu",e.CHECK_UPDATE="tauri://update",e.UPDATE_AVAILABLE="tauri://update-available",e.INSTALL_UPDATE="tauri://update-install",e.STATUS_UPDATE="tauri://update-status",e.DOWNLOAD_PROGRESS="tauri://update-download-progress",e))(c||{});async function E(n,t){return o(n,null,t)}async function _(n,t){return u(n,null,t)}async function D(n,t){return m(n,void 0,t)}
|
||||
|
||||
var LogLevel;
|
||||
(function (LogLevel) {
|
||||
/**
|
||||
* The "trace" level.
|
||||
*
|
||||
* Designates very low priority, often extremely verbose, information.
|
||||
*/
|
||||
LogLevel[LogLevel["Trace"] = 1] = "Trace";
|
||||
/**
|
||||
* The "debug" level.
|
||||
*
|
||||
* Designates lower priority information.
|
||||
*/
|
||||
LogLevel[LogLevel["Debug"] = 2] = "Debug";
|
||||
/**
|
||||
* The "info" level.
|
||||
*
|
||||
* Designates useful information.
|
||||
*/
|
||||
LogLevel[LogLevel["Info"] = 3] = "Info";
|
||||
/**
|
||||
* The "warn" level.
|
||||
*
|
||||
* Designates hazardous situations.
|
||||
*/
|
||||
LogLevel[LogLevel["Warn"] = 4] = "Warn";
|
||||
/**
|
||||
* The "error" level.
|
||||
*
|
||||
* Designates very serious errors.
|
||||
*/
|
||||
LogLevel[LogLevel["Error"] = 5] = "Error";
|
||||
})(LogLevel || (LogLevel = {}));
|
||||
async function log(level, message, options) {
|
||||
var _a, _b;
|
||||
const traces = (_a = new Error().stack) === null || _a === void 0 ? void 0 : _a.split("\n").map((line) => line.split("@"));
|
||||
const filtered = traces === null || traces === void 0 ? void 0 : traces.filter(([name, location]) => {
|
||||
return name.length > 0 && location !== "[native code]";
|
||||
});
|
||||
const { file, line, ...keyValues } = options !== null && options !== void 0 ? options : {};
|
||||
await c$1("plugin:log|log", {
|
||||
level,
|
||||
message,
|
||||
location: (_b = filtered === null || filtered === void 0 ? void 0 : filtered[0]) === null || _b === void 0 ? void 0 : _b.filter((v) => v.length > 0).join("@"),
|
||||
file,
|
||||
line,
|
||||
keyValues,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Logs a message at the error level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { error } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const err_info = "No connection";
|
||||
* const port = 22;
|
||||
*
|
||||
* error(`Error: ${err_info} on port ${port}`);
|
||||
* ```
|
||||
*/
|
||||
async function error(message, options) {
|
||||
await log(LogLevel.Error, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the warn level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { warn } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const warn_description = "Invalid Input";
|
||||
*
|
||||
* warn(`Warning! {warn_description}!`);
|
||||
* ```
|
||||
*/
|
||||
async function warn(message, options) {
|
||||
await log(LogLevel.Warn, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the info level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { info } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const conn_info = { port: 40, speed: 3.20 };
|
||||
*
|
||||
* info(`Connected to port {conn_info.port} at {conn_info.speed} Mb/s`);
|
||||
* ```
|
||||
*/
|
||||
async function info(message, options) {
|
||||
await log(LogLevel.Info, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the debug level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { debug } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const pos = { x: 3.234, y: -1.223 };
|
||||
*
|
||||
* debug(`New position: x: {pos.x}, y: {pos.y}`);
|
||||
* ```
|
||||
*/
|
||||
async function debug(message, options) {
|
||||
await log(LogLevel.Debug, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the trace level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { trace } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* let pos = { x: 3.234, y: -1.223 };
|
||||
*
|
||||
* trace(`Position is: x: {pos.x}, y: {pos.y}`);
|
||||
* ```
|
||||
*/
|
||||
async function trace(message, options) {
|
||||
await log(LogLevel.Trace, message, options);
|
||||
}
|
||||
async function attachConsole() {
|
||||
return await E("log://log", (event) => {
|
||||
const payload = event.payload;
|
||||
switch (payload.level) {
|
||||
case LogLevel.Trace:
|
||||
console.log(payload.message);
|
||||
break;
|
||||
case LogLevel.Debug:
|
||||
console.debug(payload.message);
|
||||
break;
|
||||
case LogLevel.Info:
|
||||
console.info(payload.message);
|
||||
break;
|
||||
case LogLevel.Warn:
|
||||
console.warn(payload.message);
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
console.error(payload.message);
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
throw new Error(`unknown log level ${payload.level}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export { attachConsole, debug, error, info, trace, warn };
|
||||
//# sourceMappingURL=index.min.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
Vendored
+171
@@ -0,0 +1,171 @@
|
||||
import { invoke } from '@tauri-apps/api/tauri';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
|
||||
var LogLevel;
|
||||
(function (LogLevel) {
|
||||
/**
|
||||
* The "trace" level.
|
||||
*
|
||||
* Designates very low priority, often extremely verbose, information.
|
||||
*/
|
||||
LogLevel[LogLevel["Trace"] = 1] = "Trace";
|
||||
/**
|
||||
* The "debug" level.
|
||||
*
|
||||
* Designates lower priority information.
|
||||
*/
|
||||
LogLevel[LogLevel["Debug"] = 2] = "Debug";
|
||||
/**
|
||||
* The "info" level.
|
||||
*
|
||||
* Designates useful information.
|
||||
*/
|
||||
LogLevel[LogLevel["Info"] = 3] = "Info";
|
||||
/**
|
||||
* The "warn" level.
|
||||
*
|
||||
* Designates hazardous situations.
|
||||
*/
|
||||
LogLevel[LogLevel["Warn"] = 4] = "Warn";
|
||||
/**
|
||||
* The "error" level.
|
||||
*
|
||||
* Designates very serious errors.
|
||||
*/
|
||||
LogLevel[LogLevel["Error"] = 5] = "Error";
|
||||
})(LogLevel || (LogLevel = {}));
|
||||
async function log(level, message, options) {
|
||||
var _a, _b;
|
||||
const traces = (_a = new Error().stack) === null || _a === void 0 ? void 0 : _a.split("\n").map((line) => line.split("@"));
|
||||
const filtered = traces === null || traces === void 0 ? void 0 : traces.filter(([name, location]) => {
|
||||
return name.length > 0 && location !== "[native code]";
|
||||
});
|
||||
const { file, line, ...keyValues } = options !== null && options !== void 0 ? options : {};
|
||||
await invoke("plugin:log|log", {
|
||||
level,
|
||||
message,
|
||||
location: (_b = filtered === null || filtered === void 0 ? void 0 : filtered[0]) === null || _b === void 0 ? void 0 : _b.filter((v) => v.length > 0).join("@"),
|
||||
file,
|
||||
line,
|
||||
keyValues,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Logs a message at the error level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { error } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const err_info = "No connection";
|
||||
* const port = 22;
|
||||
*
|
||||
* error(`Error: ${err_info} on port ${port}`);
|
||||
* ```
|
||||
*/
|
||||
async function error(message, options) {
|
||||
await log(LogLevel.Error, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the warn level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { warn } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const warn_description = "Invalid Input";
|
||||
*
|
||||
* warn(`Warning! {warn_description}!`);
|
||||
* ```
|
||||
*/
|
||||
async function warn(message, options) {
|
||||
await log(LogLevel.Warn, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the info level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { info } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const conn_info = { port: 40, speed: 3.20 };
|
||||
*
|
||||
* info(`Connected to port {conn_info.port} at {conn_info.speed} Mb/s`);
|
||||
* ```
|
||||
*/
|
||||
async function info(message, options) {
|
||||
await log(LogLevel.Info, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the debug level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { debug } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const pos = { x: 3.234, y: -1.223 };
|
||||
*
|
||||
* debug(`New position: x: {pos.x}, y: {pos.y}`);
|
||||
* ```
|
||||
*/
|
||||
async function debug(message, options) {
|
||||
await log(LogLevel.Debug, message, options);
|
||||
}
|
||||
/**
|
||||
* Logs a message at the trace level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { trace } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* let pos = { x: 3.234, y: -1.223 };
|
||||
*
|
||||
* trace(`Position is: x: {pos.x}, y: {pos.y}`);
|
||||
* ```
|
||||
*/
|
||||
async function trace(message, options) {
|
||||
await log(LogLevel.Trace, message, options);
|
||||
}
|
||||
async function attachConsole() {
|
||||
return await listen("log://log", (event) => {
|
||||
const payload = event.payload;
|
||||
switch (payload.level) {
|
||||
case LogLevel.Trace:
|
||||
console.log(payload.message);
|
||||
break;
|
||||
case LogLevel.Debug:
|
||||
console.debug(payload.message);
|
||||
break;
|
||||
case LogLevel.Info:
|
||||
console.info(payload.message);
|
||||
break;
|
||||
case LogLevel.Warn:
|
||||
console.warn(payload.message);
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
console.error(payload.message);
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
throw new Error(`unknown log level ${payload.level}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export { attachConsole, debug, error, info, trace, warn };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
||||
@@ -0,0 +1,206 @@
|
||||
import { invoke } from "@tauri-apps/api/tauri";
|
||||
import { listen, UnlistenFn } from "@tauri-apps/api/event";
|
||||
|
||||
export type LogOptions = {
|
||||
file?: string;
|
||||
line?: number;
|
||||
} & Record<string, string | undefined>;
|
||||
|
||||
enum LogLevel {
|
||||
/**
|
||||
* The "trace" level.
|
||||
*
|
||||
* Designates very low priority, often extremely verbose, information.
|
||||
*/
|
||||
Trace = 1,
|
||||
/**
|
||||
* The "debug" level.
|
||||
*
|
||||
* Designates lower priority information.
|
||||
*/
|
||||
Debug,
|
||||
/**
|
||||
* The "info" level.
|
||||
*
|
||||
* Designates useful information.
|
||||
*/
|
||||
Info,
|
||||
/**
|
||||
* The "warn" level.
|
||||
*
|
||||
* Designates hazardous situations.
|
||||
*/
|
||||
Warn,
|
||||
/**
|
||||
* The "error" level.
|
||||
*
|
||||
* Designates very serious errors.
|
||||
*/
|
||||
Error,
|
||||
}
|
||||
|
||||
async function log(
|
||||
level: LogLevel,
|
||||
message: string,
|
||||
options?: LogOptions
|
||||
): Promise<void> {
|
||||
const traces = new Error().stack?.split("\n").map((line) => line.split("@"));
|
||||
|
||||
const filtered = traces?.filter(([name, location]) => {
|
||||
return name.length > 0 && location !== "[native code]";
|
||||
});
|
||||
|
||||
const { file, line, ...keyValues } = options ?? {};
|
||||
|
||||
await invoke("plugin:log|log", {
|
||||
level,
|
||||
message,
|
||||
location: filtered?.[0]?.filter((v) => v.length > 0).join("@"),
|
||||
file,
|
||||
line,
|
||||
keyValues,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message at the error level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { error } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const err_info = "No connection";
|
||||
* const port = 22;
|
||||
*
|
||||
* error(`Error: ${err_info} on port ${port}`);
|
||||
* ```
|
||||
*/
|
||||
export async function error(
|
||||
message: string,
|
||||
options?: LogOptions
|
||||
): Promise<void> {
|
||||
await log(LogLevel.Error, message, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message at the warn level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { warn } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const warn_description = "Invalid Input";
|
||||
*
|
||||
* warn(`Warning! {warn_description}!`);
|
||||
* ```
|
||||
*/
|
||||
export async function warn(
|
||||
message: string,
|
||||
options?: LogOptions
|
||||
): Promise<void> {
|
||||
await log(LogLevel.Warn, message, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message at the info level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { info } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const conn_info = { port: 40, speed: 3.20 };
|
||||
*
|
||||
* info(`Connected to port {conn_info.port} at {conn_info.speed} Mb/s`);
|
||||
* ```
|
||||
*/
|
||||
export async function info(
|
||||
message: string,
|
||||
options?: LogOptions
|
||||
): Promise<void> {
|
||||
await log(LogLevel.Info, message, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message at the debug level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { debug } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* const pos = { x: 3.234, y: -1.223 };
|
||||
*
|
||||
* debug(`New position: x: {pos.x}, y: {pos.y}`);
|
||||
* ```
|
||||
*/
|
||||
export async function debug(
|
||||
message: string,
|
||||
options?: LogOptions
|
||||
): Promise<void> {
|
||||
await log(LogLevel.Debug, message, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message at the trace level.
|
||||
*
|
||||
* @param message
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```js
|
||||
* import { trace } from 'tauri-plugin-log-api';
|
||||
*
|
||||
* let pos = { x: 3.234, y: -1.223 };
|
||||
*
|
||||
* trace(`Position is: x: {pos.x}, y: {pos.y}`);
|
||||
* ```
|
||||
*/
|
||||
export async function trace(
|
||||
message: string,
|
||||
options?: LogOptions
|
||||
): Promise<void> {
|
||||
await log(LogLevel.Trace, message, options);
|
||||
}
|
||||
|
||||
interface RecordPayload {
|
||||
level: LogLevel;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export async function attachConsole(): Promise<UnlistenFn> {
|
||||
return await listen("log://log", (event) => {
|
||||
const payload = event.payload as RecordPayload;
|
||||
|
||||
switch (payload.level) {
|
||||
case LogLevel.Trace:
|
||||
console.log(payload.message);
|
||||
break;
|
||||
case LogLevel.Debug:
|
||||
console.debug(payload.message);
|
||||
break;
|
||||
case LogLevel.Info:
|
||||
console.info(payload.message);
|
||||
break;
|
||||
case LogLevel.Warn:
|
||||
console.warn(payload.message);
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
console.error(payload.message);
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
throw new Error(`unknown log level ${payload.level}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "tauri-plugin-log",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT or APACHE-2.0",
|
||||
"type": "module",
|
||||
"browser": "dist/index.min.js",
|
||||
"module": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
"import": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"browser": "./dist/index.min.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -c"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"!dist/**/*.map",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"devDependencies": {
|
||||
"tslib": "^2.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.2.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
import { createConfig } from "../../../shared/rollup.config.mjs";
|
||||
|
||||
export default createConfig({
|
||||
pkg: JSON.parse(
|
||||
readFileSync(new URL("./package.json", import.meta.url), "utf8")
|
||||
),
|
||||
external: [/^@tauri-apps\/api/],
|
||||
});
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../shared/tsconfig.json
|
||||
@@ -0,0 +1,350 @@
|
||||
// Copyright 2021 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use fern::FormatCallback;
|
||||
use log::{logger, RecordBuilder};
|
||||
use log::{LevelFilter, Record};
|
||||
use serde::Serialize;
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::{
|
||||
fmt::Arguments,
|
||||
fs::{self, File},
|
||||
iter::FromIterator,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use tauri::{
|
||||
plugin::{self, TauriPlugin},
|
||||
Manager, Runtime,
|
||||
};
|
||||
|
||||
pub use fern;
|
||||
|
||||
const DEFAULT_MAX_FILE_SIZE: u128 = 40000;
|
||||
const DEFAULT_ROTATION_STRATEGY: RotationStrategy = RotationStrategy::KeepOne;
|
||||
const DEFAULT_LOG_TARGETS: [LogTarget; 2] = [LogTarget::Stdout, LogTarget::LogDir];
|
||||
|
||||
/// An enum representing the available verbosity levels of the logger.
|
||||
///
|
||||
/// It is very similar to the [`log::Level`], but serializes to unsigned ints instead of strings.
|
||||
#[derive(Debug, Clone, Deserialize_repr, Serialize_repr)]
|
||||
#[repr(u16)]
|
||||
pub enum LogLevel {
|
||||
/// The "trace" level.
|
||||
///
|
||||
/// Designates very low priority, often extremely verbose, information.
|
||||
Trace = 1,
|
||||
/// The "debug" level.
|
||||
///
|
||||
/// Designates lower priority information.
|
||||
Debug,
|
||||
/// The "info" level.
|
||||
///
|
||||
/// Designates useful information.
|
||||
Info,
|
||||
/// The "warn" level.
|
||||
///
|
||||
/// Designates hazardous situations.
|
||||
Warn,
|
||||
/// The "error" level.
|
||||
///
|
||||
/// Designates very serious errors.
|
||||
Error,
|
||||
}
|
||||
|
||||
impl From<LogLevel> for log::Level {
|
||||
fn from(log_level: LogLevel) -> Self {
|
||||
match log_level {
|
||||
LogLevel::Trace => log::Level::Trace,
|
||||
LogLevel::Debug => log::Level::Debug,
|
||||
LogLevel::Info => log::Level::Info,
|
||||
LogLevel::Warn => log::Level::Warn,
|
||||
LogLevel::Error => log::Level::Error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<log::Level> for LogLevel {
|
||||
fn from(log_level: log::Level) -> Self {
|
||||
match log_level {
|
||||
log::Level::Trace => LogLevel::Trace,
|
||||
log::Level::Debug => LogLevel::Debug,
|
||||
log::Level::Info => LogLevel::Info,
|
||||
log::Level::Warn => LogLevel::Warn,
|
||||
log::Level::Error => LogLevel::Error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum RotationStrategy {
|
||||
KeepAll,
|
||||
KeepOne,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
struct RecordPayload {
|
||||
message: String,
|
||||
level: LogLevel,
|
||||
}
|
||||
|
||||
/// An enum representing the available targets of the logger.
|
||||
pub enum LogTarget {
|
||||
/// Print logs to stdout.
|
||||
Stdout,
|
||||
/// Print logs to stderr.
|
||||
Stderr,
|
||||
/// Write logs to the given directory.
|
||||
///
|
||||
/// The plugin will ensure the directory exists before writing logs.
|
||||
Folder(PathBuf),
|
||||
/// Write logs to the OS specififc logs directory.
|
||||
///
|
||||
/// ### Platform-specific
|
||||
///
|
||||
/// |Platform | Value | Example |
|
||||
/// | ------- | --------------------------------------------- | ---------------------------------------------- |
|
||||
/// | Linux | `{configDir}/{bundleIdentifier}` | `/home/alice/.config/com.tauri.dev` |
|
||||
/// | macOS | `{homeDir}/Library/Logs/{bundleIdentifier}` | `/Users/Alice/Library/Logs/com.tauri.dev` |
|
||||
/// | Windows | `{configDir}/{bundleIdentifier}` | `C:\Users\Alice\AppData\Roaming\com.tauri.dev` |
|
||||
LogDir,
|
||||
/// Forward logs to the webview (via the `log://log` event).
|
||||
///
|
||||
/// This requires the webview to subscribe to log events, via this plugins `attachConsole` function.
|
||||
Webview,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn log(
|
||||
level: LogLevel,
|
||||
message: String,
|
||||
location: Option<&str>,
|
||||
file: Option<&str>,
|
||||
line: Option<u32>,
|
||||
key_values: Option<HashMap<String, String>>,
|
||||
) {
|
||||
let location = location.unwrap_or("webview");
|
||||
let mut builder = RecordBuilder::new();
|
||||
builder
|
||||
.target(location)
|
||||
.level(level.into())
|
||||
.file(file)
|
||||
.line(line);
|
||||
|
||||
let key_values = key_values.unwrap_or_default();
|
||||
let mut kv = HashMap::new();
|
||||
for (k, v) in key_values.iter() {
|
||||
kv.insert(k.as_str(), v.as_str());
|
||||
}
|
||||
builder.key_values(&kv);
|
||||
|
||||
logger().log(&builder.args(format_args!("{message}")).build());
|
||||
}
|
||||
|
||||
pub struct LoggerBuilder {
|
||||
dispatch: fern::Dispatch,
|
||||
rotation_strategy: RotationStrategy,
|
||||
max_file_size: u128,
|
||||
targets: Vec<LogTarget>,
|
||||
}
|
||||
|
||||
impl Default for LoggerBuilder {
|
||||
fn default() -> Self {
|
||||
let format =
|
||||
time::format_description::parse("[[[year]-[month]-[day]][[[hour]:[minute]:[second]]")
|
||||
.unwrap();
|
||||
let dispatch = fern::Dispatch::new().format(move |out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}] {}",
|
||||
time::OffsetDateTime::now_utc().format(&format).unwrap(),
|
||||
record.target(),
|
||||
record.level(),
|
||||
message
|
||||
))
|
||||
});
|
||||
Self {
|
||||
dispatch,
|
||||
rotation_strategy: DEFAULT_ROTATION_STRATEGY,
|
||||
max_file_size: DEFAULT_MAX_FILE_SIZE,
|
||||
targets: DEFAULT_LOG_TARGETS.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LoggerBuilder {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn rotation_strategy(mut self, rotation_strategy: RotationStrategy) -> Self {
|
||||
self.rotation_strategy = rotation_strategy;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn max_file_size(mut self, max_file_size: u128) -> Self {
|
||||
self.max_file_size = max_file_size;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn format<F>(mut self, formatter: F) -> Self
|
||||
where
|
||||
F: Fn(FormatCallback, &Arguments, &Record) + Sync + Send + 'static,
|
||||
{
|
||||
self.dispatch = self.dispatch.format(formatter);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn level(mut self, level_filter: impl Into<LevelFilter>) -> Self {
|
||||
self.dispatch = self.dispatch.level(level_filter.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn level_for(mut self, module: impl Into<Cow<'static, str>>, level: LevelFilter) -> Self {
|
||||
self.dispatch = self.dispatch.level_for(module, level);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn filter<F>(mut self, filter: F) -> Self
|
||||
where
|
||||
F: Fn(&log::Metadata) -> bool + Send + Sync + 'static,
|
||||
{
|
||||
self.dispatch = self.dispatch.filter(filter);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn target(mut self, target: LogTarget) -> Self {
|
||||
self.targets.push(target);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn targets(mut self, targets: impl IntoIterator<Item = LogTarget>) -> Self {
|
||||
self.targets = Vec::from_iter(targets);
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "colored")]
|
||||
pub fn with_colors(self, colors: fern::colors::ColoredLevelConfig) -> Self {
|
||||
let format =
|
||||
time::format_description::parse("[[[year]-[month]-[day]][[[hour]:[minute]:[second]]")
|
||||
.unwrap();
|
||||
self.format(move |out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}] {}",
|
||||
time::OffsetDateTime::now_utc().format(&format).unwrap(),
|
||||
record.target(),
|
||||
colors.color(record.level()),
|
||||
message
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn build<R: Runtime>(mut self) -> TauriPlugin<R> {
|
||||
plugin::Builder::new("log")
|
||||
.invoke_handler(tauri::generate_handler![log])
|
||||
.setup(move |app_handle| {
|
||||
let app_name = &app_handle.package_info().name;
|
||||
|
||||
// setup targets
|
||||
for target in &self.targets {
|
||||
self.dispatch = self.dispatch.chain(match target {
|
||||
LogTarget::Stdout => fern::Output::from(std::io::stdout()),
|
||||
LogTarget::Stderr => fern::Output::from(std::io::stderr()),
|
||||
LogTarget::Folder(path) => {
|
||||
if !path.exists() {
|
||||
fs::create_dir_all(&path).unwrap();
|
||||
}
|
||||
|
||||
fern::log_file(get_log_file_path(
|
||||
&path,
|
||||
app_name,
|
||||
&self.rotation_strategy,
|
||||
self.max_file_size,
|
||||
)?)?
|
||||
.into()
|
||||
}
|
||||
LogTarget::LogDir => {
|
||||
let path = app_handle.path_resolver().log_dir().unwrap();
|
||||
if !path.exists() {
|
||||
fs::create_dir_all(&path).unwrap();
|
||||
}
|
||||
|
||||
fern::log_file(get_log_file_path(
|
||||
&path,
|
||||
app_name,
|
||||
&self.rotation_strategy,
|
||||
self.max_file_size,
|
||||
)?)?
|
||||
.into()
|
||||
}
|
||||
LogTarget::Webview => {
|
||||
let app_handle = app_handle.clone();
|
||||
|
||||
fern::Output::call(move |record| {
|
||||
let payload = RecordPayload {
|
||||
message: record.args().to_string(),
|
||||
level: record.level().into(),
|
||||
};
|
||||
let app_handle = app_handle.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
app_handle.emit_all("log://log", payload).unwrap();
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.dispatch.apply()?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_log_file_path(
|
||||
dir: &impl AsRef<Path>,
|
||||
app_name: &str,
|
||||
rotation_strategy: &RotationStrategy,
|
||||
max_file_size: u128,
|
||||
) -> plugin::Result<PathBuf> {
|
||||
let path = dir.as_ref().join(format!("{}.log", app_name));
|
||||
|
||||
if path.exists() {
|
||||
let log_size = File::open(&path)?.metadata()?.len() as u128;
|
||||
if log_size > max_file_size {
|
||||
match rotation_strategy {
|
||||
RotationStrategy::KeepAll => {
|
||||
let to = dir.as_ref().join(format!(
|
||||
"{}_{}.log",
|
||||
app_name,
|
||||
time::OffsetDateTime::now_utc()
|
||||
.format(
|
||||
&time::format_description::parse(
|
||||
"[year]-[month]-[day]_[hour]-[minute]-[second]"
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap(),
|
||||
));
|
||||
if to.is_file() {
|
||||
// designated rotated log file name already exists
|
||||
// highly unlikely but defensively handle anyway by adding .bak to filename
|
||||
let mut to_bak = to.clone();
|
||||
to_bak.set_file_name(format!(
|
||||
"{}.bak",
|
||||
to_bak.file_name().unwrap().to_string_lossy()
|
||||
));
|
||||
fs::rename(&to, to_bak)?;
|
||||
}
|
||||
fs::rename(&path, to)?;
|
||||
}
|
||||
RotationStrategy::KeepOne => {
|
||||
fs::remove_file(&path)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
Reference in New Issue
Block a user