Added some files

This commit is contained in:
2026-05-21 22:25:31 +02:00
parent d0fbba86f1
commit f0653489d6
3 changed files with 242 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
/* Pure CSS styles for Music Search */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
line-height: 1.5;
background-color: #f3f4f6;
}
main {
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}
#search-container {
text-align: center;
margin-bottom: 2rem;
}
#search_term {
width: 60vw;
max-width: 600px;
font-size: 1.5rem;
padding: 0.5rem;
border: 1px solid #9ca3af;
border-radius: 0.5rem;
background-color: #e5e7eb;
color: #000;
}
#search_term:focus {
outline: none;
border-color: #6b7280;
}
#clear {
font-size: 1.5rem;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.5rem;
background-color: #f97316;
color: #fff;
cursor: pointer;
margin-left: 1rem;
}
#clear:hover {
background-color: #ea580c;
}
#games-container {
font-size: 1.5rem;
}
/* Game result cards */
.bg-green-100 {
background-color: #dcfce7;
}
.p-4 {
padding: 1rem;
}
.shadow-md {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
}
.rounded-lg {
border-radius: 0.5rem;
}
.mt-6 {
margin-top: 1.5rem;
}
/* Responsive adjustments */
@media (max-width: 768px) {
#search_term {
width: 80vw;
font-size: 1.2rem;
}
#clear {
font-size: 1.2rem;
padding: 0.4rem 0.8rem;
}
}
+44
View File
@@ -0,0 +1,44 @@
package logging
import (
"github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
"go.uber.org/zap"
)
// RequestLogger is an Echo middleware that logs HTTP requests using Zap
func RequestLogger() echo.MiddlewareFunc {
return middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
LogStatus: true,
LogURI: true,
LogMethod: true,
HandleError: true,
LogValuesFunc: func(c *echo.Context, v middleware.RequestLoggerValues) error {
logger := GetLogger()
fields := []zap.Field{
zap.String("method", v.Method),
zap.String("uri", v.URI),
zap.Int("status", v.Status),
}
if v.Error != nil {
fields = append(fields, zap.String("error", v.Error.Error()))
logger.Error("Request error", fields...)
} else {
logger.Info("Request completed", fields...)
}
return nil
},
})
}
// ErrorHandler is a custom error handler that logs errors
func ErrorHandler(err error, c *echo.Context) {
logger := GetLogger()
logger.Error("Error occurred",
zap.String("method", c.Request().Method),
zap.String("path", c.Request().URL.Path),
zap.String("error", err.Error()),
)
}
+104
View File
@@ -0,0 +1,104 @@
package logging
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var (
// Logger is the global logger instance
Logger *zap.Logger
// SugaredLogger is the global sugared logger instance
SugaredLogger *zap.SugaredLogger
)
// Init initializes the logger with the specified level and config
func Init(level string, jsonOutput bool) {
var config zap.Config
// Set the log level
logLevel := zap.NewAtomicLevel()
err := logLevel.UnmarshalText([]byte(level))
if err != nil {
logLevel.SetLevel(zap.InfoLevel)
}
if jsonOutput {
// JSON output for Grafana Loki
config = zap.Config{
Level: logLevel,
Development: false,
Sampling: nil,
Encoding: "json",
EncoderConfig: zapcore.EncoderConfig{
MessageKey: "msg",
LevelKey: "level",
TimeKey: "time",
NameKey: "logger",
CallerKey: "caller",
FunctionKey: zapcore.OmitKey,
StacktraceKey: "stacktrace",
SkipLineEnding: false,
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
},
OutputPaths: []string{"stdout"},
ErrorOutputPaths: []string{"stderr"},
InitialFields: map[string]interface{}{"service": "music-server"},
}
} else {
// Human-readable output for development
config = zap.Config{
Level: logLevel,
Development: true,
Sampling: nil,
Encoding: "console",
EncoderConfig: zapcore.EncoderConfig{
MessageKey: "msg",
LevelKey: "level",
TimeKey: "time",
NameKey: "logger",
CallerKey: "caller",
FunctionKey: zapcore.OmitKey,
StacktraceKey: "stacktrace",
SkipLineEnding: false,
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
},
OutputPaths: []string{"stdout"},
ErrorOutputPaths: []string{"stderr"},
InitialFields: map[string]interface{}{"service": "music-server"},
}
}
logger, err := config.Build()
if err != nil {
panic(err)
}
Logger = logger
SugaredLogger = logger.Sugar()
}
// GetLogger returns the global logger
func GetLogger() *zap.Logger {
if Logger == nil {
Init("info", false)
}
return Logger
}
// GetSugaredLogger returns the global sugared logger
func GetSugaredLogger() *zap.SugaredLogger {
if SugaredLogger == nil {
Init("info", false)
}
return SugaredLogger
}