diff --git a/vieter/main.v b/vieter/main.v index d7a1b7d..1d86109 100644 --- a/vieter/main.v +++ b/vieter/main.v @@ -8,15 +8,14 @@ import repo const port = 8000 -const buf_size = 1_000_000 +const buf_size = 100_000 const db_name = 'pieter.db.tar.gz' struct App { web.Context - api_key string [required; web_global] - repo_dir string [required; web_global] - logger log.Log [required; web_global] + api_key string [required; web_global] + repo_dir string [required; web_global] } [noreturn] @@ -57,45 +56,35 @@ fn (mut app App) put_package(pkg string) web.Result { full_path := os.join_path_single(app.repo_dir, pkg) if os.exists(full_path) { + app.lwarn("Tried to upload duplicate package '$pkg'") + return app.text('File already exists.') } if length := app.req.header.get(.content_length) { reader_to_file(mut app.reader, length.int(), full_path) or { + app.lwarn("Failed to upload package '$pkg'") + return app.text('Failed to upload file.') } } else { + app.lwarn("Tried to upload package '$pkg' without specifying a Content-Length.") return app.text("Content-Type header isn't set.") } repo.add_package(os.join_path_single(app.repo_dir, db_name), full_path) or { + app.linfo("Failed to add package '$pkg' to database.") + os.rm(full_path) or { println('Failed to remove $full_path') } return app.text('Failed to add package to repo.') } + app.linfo("Uploaded package '$pkg'.") + return app.text('Package added successfully.') } -// ['/publish'; post] -// fn (mut app App) put_package(filename string) web.Result { -// for _, files in app.files { -// for file in files { -// filepath := os.join_path_single(app.repo_dir, file.filename) - -// if os.exists(filepath) { -// return app.text('File already exists.') -// } - -// os.write_file(filepath, file.data) or { return app.text('Failed to upload file.') } - -// return app.text('yeet') -// } -// } - -// return app.text('done') -// } - fn main() { // Configure logger log_level_str := os.getenv_opt('LOG_LEVEL') or { 'WARN' } @@ -107,16 +96,18 @@ fn main() { mut logger := log.Log{ level: log_level } + logger.set_full_logpath(log_file) logger.log_to_console_too() + // logger.set + logger.debug('Logger set up.') + logger.flush() + defer { logger.info('Flushing log file') logger.flush() logger.close() } - // logger.set - logger.info('Logger set up.') - logger.flush() // Configure web server key := os.getenv_opt('API_KEY') or { exit_with_message(1, 'No API key was provided.') } diff --git a/vieter/web/logging.v b/vieter/web/logging.v new file mode 100644 index 0000000..66426f2 --- /dev/null +++ b/vieter/web/logging.v @@ -0,0 +1,29 @@ +module web + +import log + +pub fn (mut ctx Context) log(msg &string, level log.Level) { + lock ctx.logger { + ctx.logger.send_output(msg, level) + } +} + +pub fn (mut ctx Context) lfatal(msg &string) { + ctx.log(msg, log.Level.fatal) +} + +pub fn (mut ctx Context) lerror(msg &string) { + ctx.log(msg, log.Level.error) +} + +pub fn (mut ctx Context) lwarn(msg &string) { + ctx.log(msg, log.Level.warn) +} + +pub fn (mut ctx Context) linfo(msg &string) { + ctx.log(msg, log.Level.info) +} + +pub fn (mut ctx Context) ldebug(msg &string) { + ctx.log(msg, log.Level.debug) +} diff --git a/vieter/web/web.v b/vieter/web/web.v index e98ef9b..50fd087 100644 --- a/vieter/web/web.v +++ b/vieter/web/web.v @@ -10,6 +10,7 @@ import net.http import net.urllib import time import json +import log // A type which don't get filtered inside templates pub type RawHtml = string @@ -169,6 +170,8 @@ pub mut: form_error string // Allows reading the request body reader io.BufferedReader + // Gives access to a shared logger object + logger shared log.Log } struct FileData { @@ -424,8 +427,14 @@ pub fn run(global_app &T, port int) { fn handle_conn(mut conn net.TcpConn, mut app T, routes map[string]Route) { conn.set_read_timeout(30 * time.second) conn.set_write_timeout(30 * time.second) + defer { conn.close() or {} + + lock app.logger { + app.logger.flush() + } + unsafe { free(app) } @@ -447,6 +456,10 @@ fn handle_conn(mut conn net.TcpConn, mut app T, routes map[string]Route) { return } + lock app.logger { + app.logger.debug('$head.method $head.url $head.version') + } + // req := http.parse_request(mut reader) or { // // Prevents errors from being thrown when BufferedReader is empty // if '$err' != 'none' { @@ -483,6 +496,7 @@ fn handle_conn(mut conn net.TcpConn, mut app T, routes map[string]Route) { static_files: app.static_files static_mime_types: app.static_mime_types reader: reader + logger: app.logger } // Calling middleware...