使用Golang实现从数据库获取数据并插入特定日志集的REST API
使用Golang实现从数据库获取数据并插入特定日志集的REST API 我有一个需求,需要从 MySQL 数据库获取一些数据并将其作为 JSON 返回,这一点我已经成功实现了。但我还需要帮助,将客户端 IP、客户端主机名、请求方法、请求 JSON、响应 JSON 等信息收集起来,并写入 MySQL 数据库以及一个文件中。出于安全考虑,下面的代码中已移除数据库凭据和查询语句。请尽快提供帮助,修改代码以满足我的需求。
decl.go
package main
import “database/sql”
//Output Data structure
type Readinfo struct {
Dbsrv string `json:"DB Server"`
Db string `json:"DataBase"`
Dbtable string `json:"DatabaseTable"`
Dbref *string `json:"RefreshFrequency"`
Dbreftime *string `json:"RefreshTimeEST"`
Dbrefdur int `json:"RefreshDurationMin"`
}
//Global Variables
var (
db *sql.DB
err error
dbUser =
dbDriver = “mysql”
dbPass =
Prtcl =
dbServer =
dbPort =
statement =
)
Connect.go:
package main
import (
“database/sql”
“fmt”
_“mysql”
“mux”
“log”
“net/http”
)
//Function to open DB connection
func CreateConnection() {
db, err = sql.Open(dbDriver, dbUser+":"+dbPass+"@"+Prtcl+"("+dbServer+":"+dbPort+")"+"/")
if err != nil {
log.Println(“DB Connection Failed to Open”)
fmt.Println(err.Error())
} else {
log.Println(“DB Connection Established Successfully”)
}
defer db.Close()
err = db.Ping()
if err != nil {
fmt.Print(err.Error())
}
//Launch Router to serve Request-Response
router := mux.NewRouter()
router.HandleFunc("/read", Logging(Getdetails)).Methods(“POST”)
log.Fatal(http.ListenAndServe(":8000", router))
fmt.Println(“Routes are Loded.”)
}
act.go:
package main
import (
_“database/sql”
“encoding/json”
“fmt”
“net/http”
)
//Request-Response Handler
func Getdetails(w http.ResponseWriter, r *http.Request) {
w.Header().Set(“Content-Type”, “application/json”)
var read []Readinfo
result, err := db.Query(statement)
if err != nil {
fmt.Println(err.Error())
}
defer result.Close()
for result.Next() {
var data Readinfo
err := result.Scan(&data.Dbsrv, &data.Db, &data.Dbtable, &data.Dbref, &data.Dbreftime, &data.Dbrefdur)
if err != nil {
fmt.Println(err.Error())
}
read = append(read, data)
}
json.NewEncoder(w).Encode(read)
}
main.go:
package main
func main() {
CreateConnection()
}
更多关于使用Golang实现从数据库获取数据并插入特定日志集的REST API的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于使用Golang实现从数据库获取数据并插入特定日志集的REST API的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net"
"net/http"
"os"
"strings"
"time"
"github.com/gorilla/mux"
_ "github.com/go-sql-driver/mysql"
)
// 日志数据结构
type LogEntry struct {
ID int `json:"id"`
ClientIP string `json:"client_ip"`
ClientHost string `json:"client_host"`
RequestMethod string `json:"request_method"`
RequestJSON string `json:"request_json"`
ResponseJSON string `json:"response_json"`
Timestamp time.Time `json:"timestamp"`
}
// 全局变量
var (
db *sql.DB
logDB *sql.DB // 用于日志的数据库连接
logFile *os.File
dbUser = "your_username"
dbPass = "your_password"
dbHost = "localhost"
dbPort = "3306"
dbName = "your_database"
logDBName = "log_database"
query = "SELECT * FROM your_table"
)
// 初始化日志系统
func initLogging() error {
var err error
// 打开日志文件
logFile, err = os.OpenFile("api.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
// 连接日志数据库
logDB, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s",
dbUser, dbPass, dbHost, dbPort, logDBName))
if err != nil {
return err
}
// 创建日志表(如果不存在)
createTableSQL := `
CREATE TABLE IF NOT EXISTS api_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
client_ip VARCHAR(45),
client_host VARCHAR(255),
request_method VARCHAR(10),
request_json TEXT,
response_json TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)`
_, err = logDB.Exec(createTableSQL)
return err
}
// 获取客户端信息
func getClientInfo(r *http.Request) (string, string) {
clientIP := r.RemoteAddr
if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
clientIP = strings.Split(forwarded, ",")[0]
}
host, _, _ := net.SplitHostPort(clientIP)
if host == "" {
host = clientIP
}
hostname, _ := net.LookupAddr(host)
clientHost := host
if len(hostname) > 0 {
clientHost = hostname[0]
}
return host, clientHost
}
// 记录日志到数据库和文件
func logRequest(clientIP, clientHost, method, reqJSON, respJSON string) error {
timestamp := time.Now()
// 写入数据库
insertSQL := `INSERT INTO api_logs
(client_ip, client_host, request_method, request_json, response_json, timestamp)
VALUES (?, ?, ?, ?, ?, ?)`
_, err := logDB.Exec(insertSQL, clientIP, clientHost, method, reqJSON, respJSON, timestamp)
if err != nil {
return err
}
// 写入文件
logEntry := LogEntry{
ClientIP: clientIP,
ClientHost: clientHost,
RequestMethod: method,
RequestJSON: reqJSON,
ResponseJSON: respJSON,
Timestamp: timestamp,
}
logJSON, _ := json.Marshal(logEntry)
logFile.WriteString(string(logJSON) + "\n")
return nil
}
// 中间件:记录日志
func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 获取请求体
var requestBody map[string]interface{}
json.NewDecoder(r.Body).Decode(&requestBody)
reqJSON, _ := json.Marshal(requestBody)
// 创建自定义ResponseWriter来捕获响应
rw := &responseWriter{w, http.StatusOK, []byte{}}
// 处理请求
next(rw, r)
// 获取客户端信息
clientIP, clientHost := getClientInfo(r)
// 记录日志
err := logRequest(clientIP, clientHost, r.Method, string(reqJSON), string(rw.body))
if err != nil {
log.Printf("Failed to log request: %v", err)
}
}
}
// 自定义ResponseWriter
type responseWriter struct {
http.ResponseWriter
statusCode int
body []byte
}
func (rw *responseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}
func (rw *responseWriter) Write(b []byte) (int, error) {
rw.body = b
return rw.ResponseWriter.Write(b)
}
// 主处理函数
func Getdetails(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
rows, err := db.Query(query)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer rows.Close()
var results []Readinfo
for rows.Next() {
var data Readinfo
err := rows.Scan(&data.Dbsrv, &data.Db, &data.Dbtable, &data.Dbref, &data.Dbreftime, &data.Dbrefdur)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
results = append(results, data)
}
json.NewEncoder(w).Encode(results)
}
// 初始化数据库连接
func CreateConnection() {
var err error
// 连接主数据库
db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s",
dbUser, dbPass, dbHost, dbPort, dbName))
if err != nil {
log.Fatal(err)
}
// 初始化日志系统
err = initLogging()
if err != nil {
log.Fatal(err)
}
// 设置路由
router := mux.NewRouter()
router.HandleFunc("/read", loggingMiddleware(Getdetails)).Methods("POST")
log.Println("Server starting on :8000")
log.Fatal(http.ListenAndServe(":8000", router))
}
func main() {
CreateConnection()
}
需要安装的依赖:
go get github.com/gorilla/mux
go get github.com/go-sql-driver/mysql
日志表SQL:
CREATE TABLE api_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
client_ip VARCHAR(45),
client_host VARCHAR(255),
request_method VARCHAR(10),
request_json TEXT,
response_json TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
这个实现提供了:
- 客户端IP和主机名获取
- 请求和响应JSON记录
- 同时写入MySQL数据库和文件
- 使用中间件模式进行日志记录
- 自定义ResponseWriter捕获响应内容

