25/04/2026 02:48am

EP.72 Implementing Message Logging in WebSocket Chat with Go
#Real-Time Chat
#PostgreSQL
#chat system
#Message Logging
#Go
#WebSocket
In this episode, we’ll explore how to build a message logging system for WebSocket chat applications using Go. This system enables real-time recording of chat messages sent to and from the WebSocket server, and stores them in a database for later access by users.
Message logging is a crucial part of any chat platform. It helps in preserving conversation history, auditing user behavior, troubleshooting system issues, and providing an improved user experience by allowing users to review past messages.
Why Use Message Logging in WebSocket?
Implementing a message logging system brings several benefits:
- Chat history tracking: All messages are stored persistently and can be retrieved later
- Conversation review: Admins or users can check messages sent at any point in time
- Security & moderation: Helps monitor user behavior and prevent inappropriate usage
- Data recovery: Logged messages allow for recovery in case of system crashes or unexpected shutdowns
System Architecture Overview
A complete message logging system consists of:
- Saving messages into the database
Every chat message is saved with metadata such as sender, content, timestamp, and optionally a room ID - Receiving messages via WebSocket
The WebSocket server receives messages in real time and immediately logs them - Fetching past messages
The backend provides a way to retrieve previously logged messages (e.g., for chat history display)
Logging Messages in WebSocket Server (Go)
We will set up a WebSocket server and connect it to a PostgreSQL database to store messages in real time.
1. Setting up the WebSocket Server
package main
import (
"database/sql"
"log"
"net/http"
"sync"
"time"
"github.com/gorilla/websocket"
_ "github.com/lib/pq"
)
var (
clients = make(map[*websocket.Conn]bool)
clientsMu sync.Mutex
broadcast = make(chan Message)
db *sql.DB
)
type Message struct {
User string `json:"user"`
Message string `json:"message"`
Time time.Time `json:"time"`
}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func init() {
var err error
db, err = sql.Open("postgres", "user=username dbname=websocket_chat sslmode=disable")
if err != nil {
log.Fatal("Database connection error:", err)
}
}
func handleConnections(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Upgrade error:", err)
return
}
defer conn.Close()
clientsMu.Lock()
clients[conn] = true
clientsMu.Unlock()
for {
var msg Message
if err := conn.ReadJSON(&msg); err != nil {
log.Println("Read error:", err)
clientsMu.Lock()
delete(clients, conn)
clientsMu.Unlock()
break
}
msg.Time = time.Now()
saveMessage(msg)
broadcast <- msg
}
}
func saveMessage(msg Message) {
_, err := db.Exec("INSERT INTO messages (user, message, time) VALUES ($1, $2, $3)", msg.User, msg.Message, msg.Time)
if err != nil {
log.Println("Save message error:", err)
}
}
func handleMessages() {
for msg := range broadcast {
clientsMu.Lock()
for client := range clients {
if err := client.WriteJSON(msg); err != nil {
log.Println("Broadcast error:", err)
client.Close()
delete(clients, client)
}
}
clientsMu.Unlock()
}
}
func main() {
http.HandleFunc("/ws", handleConnections)
go handleMessages()
log.Println("Server started on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
2. Creating the PostgreSQL Table
CREATE TABLE messages (
id SERIAL PRIMARY KEY,
user VARCHAR(100),
message TEXT,
time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
3. Fetching Past Messages
func getMessages() ([]Message, error) {
rows, err := db.Query("SELECT user, message, time FROM messages ORDER BY time DESC")
if err != nil {
return nil, err
}
defer rows.Close()
var messages []Message
for rows.Next() {
var msg Message
if err := rows.Scan(&msg.User, &msg.Message, &msg.Time); err != nil {
return nil, err
}
messages = append(messages, msg)
}
return messages, nil
}
How to Test the Logging System
Make sure to cover the following test cases:
- ✅ Message persistence: Messages sent from clients must be stored correctly in the database
- ✅ History retrieval: Ensure past messages can be fetched accurately
- ✅ Performance under load: Test the server's ability to handle many clients and high message volumes
Challenge for You!
Try adding a search feature to the chat history — allowing users to look up messages based on keywords or time ranges!
Next EP:
In EP.73, we’ll explore WebSocket Compression — a technique that improves bandwidth usage and speeds up message transmission in WebSocket-based systems.
Read more
🔵 Facebook: Superdev School (Superdev)
📸 Instagram: superdevschool
🎬 TikTok: superdevschool
🌐 Website: www.superdev.school