diff --git a/.env.example b/.env.example index 11a34fc..2661515 100644 --- a/.env.example +++ b/.env.example @@ -12,3 +12,9 @@ DB_TYPE=sqlite # Database write interval in seconds (0 for real-time) DB_INTERVAL=60 + +# Log level: either 'debug' | 'info' | 'warn' | 'error' | 'none' +LOG_LEVEL=debug + +# Google Analytics `G-Tag` ID +# GA_ID=G-XXXX diff --git a/.gitignore b/.gitignore index b329f95..b079941 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ count.db # misc .DS_Store +.env .env.local .env.development.local .env.test.local diff --git a/assets/script.js b/assets/script.js index 9babf1a..27b8aed 100644 --- a/assets/script.js +++ b/assets/script.js @@ -145,8 +145,8 @@ const lazyLoadOptions = { selector: 'img[data-src]:not([src])', - loading: '/img/loading.svg', - failed: '/img/failed.svg', + loading: `${__global_data.site}/img/loading.svg`, + failed: `${__global_data.site}/img/failed.svg`, rootMargin: '200px', threshold: 0.01 }; diff --git a/index.js b/index.js index ac994ba..66e0a3c 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ const { z } = require("zod"); const db = require("./db"); const { themeList, getCountImage } = require("./utils/themify"); const { cors, ZodValid } = require("./utils/middleware"); -const { randomArray } = require("./utils"); +const { randomArray, logger } = require("./utils"); const app = express(); @@ -19,8 +19,10 @@ app.set("view engine", "pug"); app.get('/', (req, res) => { const site = process.env.APP_SITE || `${req.protocol}://${req.get('host')}` + const ga_id = process.env.GA_ID || null res.render('index', { site, + ga_id, themeList, }) }); @@ -71,7 +73,7 @@ app.get(["/@:name", "/get/@:name"], res.send(renderSvg); - console.log( + logger.debug( data, { theme, ...req.query }, `ip: ${req.headers['x-forwarded-for'] || req.connection.remoteAddress}`, @@ -93,11 +95,11 @@ app.get("/record/@:name", async (req, res) => { app.get("/heart-beat", (req, res) => { res.set("cache-control", "max-age=0, no-cache, no-store, must-revalidate"); res.send("alive"); - console.log("heart-beat"); + logger.debug("heart-beat"); }); const listener = app.listen(process.env.APP_PORT || 3000, () => { - console.log("Your app is listening on port " + listener.address().port); + logger.info("Your app is listening on port " + listener.address().port); }); let __cache_counter = {}; @@ -116,7 +118,7 @@ async function pushDB() { try { needPush = false; - console.log("pushDB", __cache_counter); + logger.info("pushDB", __cache_counter); const counters = Object.keys(__cache_counter).map((key) => { return { @@ -128,7 +130,7 @@ async function pushDB() { await db.setNumMulti(counters); __cache_counter = {}; } catch (error) { - console.log("pushDB is error: ", error); + logger.error("pushDB is error: ", error); } } @@ -151,7 +153,7 @@ async function getCountByName(name, num) { return { name, num: __cache_counter[name] }; } catch (error) { - console.log("get count by name is error: ", error); + logger.error("get count by name is error: ", error); return defaultCount; } } diff --git a/utils/index.js b/utils/index.js index 687737b..f369e06 100644 --- a/utils/index.js +++ b/utils/index.js @@ -1,8 +1,28 @@ +const log_level = process.env.LOG_LEVEL || 'info'; + +const levels = ['none', 'error', 'warn', 'info', 'debug']; +const currentLevelIndex = levels.indexOf(log_level); + +const buildLogMethod = (level) => (...args) => { + const levelIndex = levels.indexOf(level); + const shouldLog = levelIndex <= currentLevelIndex; + + if (shouldLog) { + console[level](...args); + } +}; + module.exports = { randomArray: (arr) => { return arr[Math.floor(Math.random() * arr.length)] }, toFixed: (num, digits = 2) => { return parseFloat(Number(num).toFixed(digits)) + }, + logger: { + debug: buildLogMethod('debug'), + info: buildLogMethod('info'), + warn: buildLogMethod('warn'), + error: buildLogMethod('error') } } diff --git a/views/index.pug b/views/index.pug index 5e5303d..fa489f7 100644 --- a/views/index.pug +++ b/views/index.pug @@ -2,19 +2,20 @@ html head title='Moe Counter!' meta(name='viewport', content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no') - link(rel='icon', type='image/png', href='favicon.png') + link(rel='icon', type='image/png', href=`${site}/favicon.png`) link(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/normalize.css') link(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/bamboo.css') - link(rel='stylesheet/less', href='style.less') + link(rel='stylesheet/less', href=`${site}/style.less`) script(less, src='https://cdn.jsdelivr.net/npm/less') - - script(async, src='https://www.googletagmanager.com/gtag/js?id=G-2RLWN5JXRL') + if ga_id + + script(async, src='https://www.googletagmanager.com/gtag/js?id=#{ga_id}') script. window.dataLayer = window.dataLayer || []; - function gtag() {dataLayer.push(arguments); } + function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); - gtag('config', 'G-2RLWN5JXRL'); + gtag('config', '#{ga_id}'); function _evt_push(type, category, label) { gtag('event', type, { @@ -148,4 +149,4 @@ html div.back-to-top script(async, src='https://cdn.jsdelivr.net/npm/party-js@2/bundle/party.min.js') - script(async, src='script.js') + script(async, src=`${site}/script.js`)