add a unified logging handler to the http client
This commit is contained in:
@@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const openStreetMapTileImageUrlFormat = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" // https://tile.openstreetmap.org/{z}/{x}/{y}.png
|
const openStreetMapTileImageUrlFormat = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" // https://tile.openstreetmap.org/{z}/{x}/{y}.png
|
||||||
@@ -110,7 +110,7 @@ func (p *MapImageProxy) mapImageProxyHandler(c *core.WebContext, fn func(c *core
|
|||||||
}
|
}
|
||||||
|
|
||||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||||
utils.SetProxyUrl(transport, p.CurrentConfig().MapProxy)
|
httpclient.SetProxyUrl(transport, p.CurrentConfig().MapProxy)
|
||||||
|
|
||||||
director := func(req *http.Request) {
|
director := func(req *http.Request) {
|
||||||
imageRawUrl := targetUrl
|
imageRawUrl := targetUrl
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider/oidc"
|
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider/oidc"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OAuth2Container contains the current OAuth 2.0 authentication provider
|
// OAuth2Container contains the current OAuth 2.0 authentication provider
|
||||||
@@ -67,7 +67,7 @@ func InitializeOAuth2Provider(config *settings.Config) error {
|
|||||||
|
|
||||||
Container.current = oauth2Provider
|
Container.current = oauth2Provider
|
||||||
Container.usePKCE = config.OAuth2UsePKCE
|
Container.usePKCE = config.OAuth2UsePKCE
|
||||||
Container.oauth2HttpClient = utils.NewHttpClient(config.OAuth2RequestTimeout, config.OAuth2Proxy, config.OAuth2SkipTLSVerify, settings.GetUserAgent())
|
Container.oauth2HttpClient = httpclient.NewHttpClient(config.OAuth2RequestTimeout, config.OAuth2Proxy, config.OAuth2SkipTLSVerify, settings.GetUserAgent(), config.EnableDebugLog)
|
||||||
Container.externalUserAuthType = externalUserAuthType
|
Container.externalUserAuthType = externalUserAuthType
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider"
|
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
)
|
)
|
||||||
@@ -59,6 +60,11 @@ func (p *CommonOAuth2Provider) GetUserInfo(c core.Context, oauth2Token *oauth2.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
oauth2Client := oauth2.NewClient(c, oauth2.StaticTokenSource(oauth2Token))
|
oauth2Client := oauth2.NewClient(c, oauth2.StaticTokenSource(oauth2Token))
|
||||||
|
|
||||||
|
req = req.WithContext(httpclient.CustomHttpResponseLog(c, func(data []byte) {
|
||||||
|
log.Debugf(c, "[common_oauth2_provider.GetUserInfo] response is %s", data)
|
||||||
|
}))
|
||||||
|
|
||||||
resp, err := oauth2Client.Do(req)
|
resp, err := oauth2Client.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -69,8 +75,6 @@ func (p *CommonOAuth2Provider) GetUserInfo(c core.Context, oauth2Token *oauth2.T
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
log.Debugf(c, "[common_oauth2_provider.GetUserInfo] response is %s", body)
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Errorf(c, "[common_oauth2_provider.GetUserInfo] failed to get user info response, because response code is %d", resp.StatusCode)
|
log.Errorf(c, "[common_oauth2_provider.GetUserInfo] failed to get user info response, because response code is %d", resp.StatusCode)
|
||||||
return nil, errs.ErrFailedToRequestRemoteApi
|
return nil, errs.ErrFailedToRequestRemoteApi
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider"
|
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
)
|
)
|
||||||
@@ -61,6 +62,11 @@ func (p *GithubOAuth2Provider) GetUserInfo(c core.Context, oauth2Token *oauth2.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
oauth2Client := oauth2.NewClient(c, oauth2.StaticTokenSource(oauth2Token))
|
oauth2Client := oauth2.NewClient(c, oauth2.StaticTokenSource(oauth2Token))
|
||||||
|
|
||||||
|
req = req.WithContext(httpclient.CustomHttpResponseLog(c, func(data []byte) {
|
||||||
|
log.Debugf(c, "[github_oauth2_provider.GetUserInfo] user profile response is %s", data)
|
||||||
|
}))
|
||||||
|
|
||||||
resp, err := oauth2Client.Do(req)
|
resp, err := oauth2Client.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -71,8 +77,6 @@ func (p *GithubOAuth2Provider) GetUserInfo(c core.Context, oauth2Token *oauth2.T
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
log.Debugf(c, "[github_oauth2_provider.GetUserInfo] user profile response is %s", body)
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Errorf(c, "[github_oauth2_provider.GetUserInfo] failed to get user info response, because response code is %d", resp.StatusCode)
|
log.Errorf(c, "[github_oauth2_provider.GetUserInfo] failed to get user info response, because response code is %d", resp.StatusCode)
|
||||||
return nil, errs.ErrFailedToRequestRemoteApi
|
return nil, errs.ErrFailedToRequestRemoteApi
|
||||||
@@ -92,6 +96,10 @@ func (p *GithubOAuth2Provider) GetUserInfo(c core.Context, oauth2Token *oauth2.T
|
|||||||
return nil, errs.ErrFailedToRequestRemoteApi
|
return nil, errs.ErrFailedToRequestRemoteApi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req = req.WithContext(httpclient.CustomHttpResponseLog(c, func(data []byte) {
|
||||||
|
log.Debugf(c, "[github_oauth2_provider.GetUserInfo] user emails response is %s", data)
|
||||||
|
}))
|
||||||
|
|
||||||
resp, err = oauth2Client.Do(req)
|
resp, err = oauth2Client.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -102,8 +110,6 @@ func (p *GithubOAuth2Provider) GetUserInfo(c core.Context, oauth2Token *oauth2.T
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err = io.ReadAll(resp.Body)
|
body, err = io.ReadAll(resp.Body)
|
||||||
|
|
||||||
log.Debugf(c, "[github_oauth2_provider.GetUserInfo] user emails response is %s", body)
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Errorf(c, "[github_oauth2_provider.GetUserInfo] failed to get user emails response, because response code is %d", resp.StatusCode)
|
log.Errorf(c, "[github_oauth2_provider.GetUserInfo] failed to get user emails response, because response code is %d", resp.StatusCode)
|
||||||
return nil, errs.ErrFailedToRequestRemoteApi
|
return nil, errs.ErrFailedToRequestRemoteApi
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider"
|
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2/provider"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
)
|
)
|
||||||
@@ -92,7 +93,9 @@ func (p *OIDCProvider) GetUserInfo(c core.Context, oauth2Token *oauth2.Token) (*
|
|||||||
nickName := claims.Name
|
nickName := claims.Name
|
||||||
|
|
||||||
if userName == "" || email == "" || nickName == "" {
|
if userName == "" || email == "" || nickName == "" {
|
||||||
userInfo, err := p.oidcProvider.UserInfo(c, oauth2.StaticTokenSource(oauth2Token))
|
userInfo, err := p.oidcProvider.UserInfo(httpclient.CustomHttpResponseLog(c, func(data []byte) {
|
||||||
|
log.Debugf(c, "[oidc_provider.GetUserInfo] response is %s", data)
|
||||||
|
}), oauth2.StaticTokenSource(oauth2Token))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[oidc_provider.GetUserInfo] failed to get user info, because %s", err.Error())
|
log.Errorf(c, "[oidc_provider.GetUserInfo] failed to get user info, because %s", err.Error())
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import (
|
|||||||
|
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/models"
|
"github.com/mayswind/ezbookkeeping/pkg/models"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// HttpExchangeRatesDataSource defines the structure of http exchange rates data source
|
// HttpExchangeRatesDataSource defines the structure of http exchange rates data source
|
||||||
@@ -41,6 +41,10 @@ func (e *CommonHttpExchangeRatesDataProvider) GetLatestExchangeRates(c core.Cont
|
|||||||
|
|
||||||
for i := 0; i < len(requests); i++ {
|
for i := 0; i < len(requests); i++ {
|
||||||
req := requests[i]
|
req := requests[i]
|
||||||
|
req = req.WithContext(httpclient.CustomHttpResponseLog(c, func(data []byte) {
|
||||||
|
log.Debugf(c, "[common_http_exchange_rates_data_provider.GetLatestExchangeRates] response#%d is %s", i, data)
|
||||||
|
}))
|
||||||
|
|
||||||
resp, err := e.httpClient.Do(req)
|
resp, err := e.httpClient.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -51,8 +55,6 @@ func (e *CommonHttpExchangeRatesDataProvider) GetLatestExchangeRates(c core.Cont
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
log.Debugf(c, "[common_http_exchange_rates_data_provider.GetLatestExchangeRates] response#%d is %s", i, body)
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Errorf(c, "[common_http_exchange_rates_data_provider.GetLatestExchangeRates] failed to get latest exchange rate data response for user \"uid:%d\", because response code is %d", uid, resp.StatusCode)
|
log.Errorf(c, "[common_http_exchange_rates_data_provider.GetLatestExchangeRates] failed to get latest exchange rate data response for user \"uid:%d\", because response code is %d", uid, resp.StatusCode)
|
||||||
return nil, errs.ErrFailedToRequestRemoteApi
|
return nil, errs.ErrFailedToRequestRemoteApi
|
||||||
@@ -106,6 +108,6 @@ func (e *CommonHttpExchangeRatesDataProvider) GetLatestExchangeRates(c core.Cont
|
|||||||
func newCommonHttpExchangeRatesDataProvider(config *settings.Config, dataSource HttpExchangeRatesDataSource) *CommonHttpExchangeRatesDataProvider {
|
func newCommonHttpExchangeRatesDataProvider(config *settings.Config, dataSource HttpExchangeRatesDataSource) *CommonHttpExchangeRatesDataProvider {
|
||||||
return &CommonHttpExchangeRatesDataProvider{
|
return &CommonHttpExchangeRatesDataProvider{
|
||||||
dataSource: dataSource,
|
dataSource: dataSource,
|
||||||
httpClient: utils.NewHttpClient(config.ExchangeRatesRequestTimeout, config.ExchangeRatesProxy, config.ExchangeRatesSkipTLSVerify, settings.GetUserAgent()),
|
httpClient: httpclient.NewHttpClient(config.ExchangeRatesRequestTimeout, config.ExchangeRatesProxy, config.ExchangeRatesSkipTLSVerify, settings.GetUserAgent(), config.EnableDebugLog),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
package utils
|
package httpclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type defaultTransport struct {
|
type defaultTransport struct {
|
||||||
defaultUserAgent string
|
defaultUserAgent string
|
||||||
baseTransport http.RoundTripper
|
enableHttpResponseLog bool
|
||||||
|
baseTransport http.RoundTripper
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *defaultTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
func (t *defaultTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
@@ -19,11 +22,30 @@ func (t *defaultTransport) RoundTrip(req *http.Request) (*http.Response, error)
|
|||||||
req.Header.Del("User-Agent")
|
req.Header.Del("User-Agent")
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.baseTransport.RoundTrip(req)
|
resp, err := t.baseTransport.RoundTrip(req)
|
||||||
|
|
||||||
|
if t.enableHttpResponseLog && err == nil {
|
||||||
|
ctx := req.Context()
|
||||||
|
|
||||||
|
if handler, ok := ctx.Value(logHandleKey).(HttpResponseLogHandlerFunc); ok {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
handler(body)
|
||||||
|
|
||||||
|
resp.Body = io.NopCloser(bytes.NewReader(body))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHttpClient creates and returns a new http client with specified settings
|
// NewHttpClient creates and returns a new http client with specified settings
|
||||||
func NewHttpClient(requestTimeout uint32, proxy string, skipTLSVerify bool, defaultUserAgent string) *http.Client {
|
func NewHttpClient(requestTimeout uint32, proxy string, skipTLSVerify bool, defaultUserAgent string, enableHttpResponseLog bool) *http.Client {
|
||||||
baseTransport := http.DefaultTransport.(*http.Transport).Clone()
|
baseTransport := http.DefaultTransport.(*http.Transport).Clone()
|
||||||
SetProxyUrl(baseTransport, proxy)
|
SetProxyUrl(baseTransport, proxy)
|
||||||
|
|
||||||
@@ -35,8 +57,9 @@ func NewHttpClient(requestTimeout uint32, proxy string, skipTLSVerify bool, defa
|
|||||||
|
|
||||||
return &http.Client{
|
return &http.Client{
|
||||||
Transport: &defaultTransport{
|
Transport: &defaultTransport{
|
||||||
defaultUserAgent: defaultUserAgent,
|
defaultUserAgent: defaultUserAgent,
|
||||||
baseTransport: baseTransport,
|
enableHttpResponseLog: enableHttpResponseLog,
|
||||||
|
baseTransport: baseTransport,
|
||||||
},
|
},
|
||||||
Timeout: time.Duration(requestTimeout) * time.Millisecond,
|
Timeout: time.Duration(requestTimeout) * time.Millisecond,
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package httpclient
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
logHandleKey = "log_handler"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HttpResponseLogHandlerFunc represents the http response log handler function
|
||||||
|
type HttpResponseLogHandlerFunc func([]byte)
|
||||||
|
|
||||||
|
// httpRequestContext represents the context for http request
|
||||||
|
type httpRequestContext struct {
|
||||||
|
core.Context
|
||||||
|
logHandler HttpResponseLogHandlerFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the value associated with key
|
||||||
|
func (c *httpRequestContext) Value(key any) any {
|
||||||
|
if key == logHandleKey {
|
||||||
|
return c.logHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Context.Value(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CustomHttpResponseLog returns a context with http response log handler
|
||||||
|
func CustomHttpResponseLog(c core.Context, responseLogHandler HttpResponseLogHandlerFunc) core.Context {
|
||||||
|
return &httpRequestContext{
|
||||||
|
Context: c,
|
||||||
|
logHandler: responseLogHandler,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ func InitializeLargeLanguageModelProvider(config *settings.Config) error {
|
|||||||
var err error = nil
|
var err error = nil
|
||||||
|
|
||||||
if config.ReceiptImageRecognitionLLMConfig != nil {
|
if config.ReceiptImageRecognitionLLMConfig != nil {
|
||||||
Container.receiptImageRecognitionCurrentProvider, err = initializeLargeLanguageModelProvider(config.ReceiptImageRecognitionLLMConfig)
|
Container.receiptImageRecognitionCurrentProvider, err = initializeLargeLanguageModelProvider(config.ReceiptImageRecognitionLLMConfig, config.EnableDebugLog)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -36,17 +36,17 @@ func InitializeLargeLanguageModelProvider(config *settings.Config) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func initializeLargeLanguageModelProvider(llmConfig *settings.LLMConfig) (provider.LargeLanguageModelProvider, error) {
|
func initializeLargeLanguageModelProvider(llmConfig *settings.LLMConfig, enableResponseLog bool) (provider.LargeLanguageModelProvider, error) {
|
||||||
if llmConfig.LLMProvider == settings.OpenAILLMProvider {
|
if llmConfig.LLMProvider == settings.OpenAILLMProvider {
|
||||||
return openai.NewOpenAILargeLanguageModelProvider(llmConfig), nil
|
return openai.NewOpenAILargeLanguageModelProvider(llmConfig, enableResponseLog), nil
|
||||||
} else if llmConfig.LLMProvider == settings.OpenAICompatibleLLMProvider {
|
} else if llmConfig.LLMProvider == settings.OpenAICompatibleLLMProvider {
|
||||||
return openai.NewOpenAICompatibleLargeLanguageModelProvider(llmConfig), nil
|
return openai.NewOpenAICompatibleLargeLanguageModelProvider(llmConfig, enableResponseLog), nil
|
||||||
} else if llmConfig.LLMProvider == settings.OpenRouterLLMProvider {
|
} else if llmConfig.LLMProvider == settings.OpenRouterLLMProvider {
|
||||||
return openai.NewOpenRouterLargeLanguageModelProvider(llmConfig), nil
|
return openai.NewOpenRouterLargeLanguageModelProvider(llmConfig, enableResponseLog), nil
|
||||||
} else if llmConfig.LLMProvider == settings.OllamaLLMProvider {
|
} else if llmConfig.LLMProvider == settings.OllamaLLMProvider {
|
||||||
return ollama.NewOllamaLargeLanguageModelProvider(llmConfig), nil
|
return ollama.NewOllamaLargeLanguageModelProvider(llmConfig, enableResponseLog), nil
|
||||||
} else if llmConfig.LLMProvider == settings.GoogleAILLMProvider {
|
} else if llmConfig.LLMProvider == settings.GoogleAILLMProvider {
|
||||||
return googleai.NewGoogleAILargeLanguageModelProvider(llmConfig), nil
|
return googleai.NewGoogleAILargeLanguageModelProvider(llmConfig, enableResponseLog), nil
|
||||||
} else if llmConfig.LLMProvider == "" {
|
} else if llmConfig.LLMProvider == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import (
|
|||||||
|
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/llm/data"
|
"github.com/mayswind/ezbookkeeping/pkg/llm/data"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/llm/provider"
|
"github.com/mayswind/ezbookkeeping/pkg/llm/provider"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// HttpLargeLanguageModelAdapter defines the structure of http large language model adapter
|
// HttpLargeLanguageModelAdapter defines the structure of http large language model adapter
|
||||||
@@ -57,6 +57,10 @@ func (p *CommonHttpLargeLanguageModelProvider) getTextualResponse(c core.Context
|
|||||||
return nil, errs.ErrFailedToRequestRemoteApi
|
return nil, errs.ErrFailedToRequestRemoteApi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
httpRequest = httpRequest.WithContext(httpclient.CustomHttpResponseLog(c, func(data []byte) {
|
||||||
|
log.Debugf(c, "[common_http_large_language_model_provider.getTextualResponse] response is %s", data)
|
||||||
|
}))
|
||||||
|
|
||||||
resp, err := p.httpClient.Do(httpRequest)
|
resp, err := p.httpClient.Do(httpRequest)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -67,8 +71,6 @@ func (p *CommonHttpLargeLanguageModelProvider) getTextualResponse(c core.Context
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
log.Debugf(c, "[common_http_large_language_model_provider.getTextualResponse] response is %s", body)
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Errorf(c, "[common_http_large_language_model_provider.getTextualResponse] failed to get large language model api response for user \"uid:%d\", because response code is %d", uid, resp.StatusCode)
|
log.Errorf(c, "[common_http_large_language_model_provider.getTextualResponse] failed to get large language model api response for user \"uid:%d\", because response code is %d", uid, resp.StatusCode)
|
||||||
return nil, errs.ErrFailedToRequestRemoteApi
|
return nil, errs.ErrFailedToRequestRemoteApi
|
||||||
@@ -78,9 +80,9 @@ func (p *CommonHttpLargeLanguageModelProvider) getTextualResponse(c core.Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCommonHttpLargeLanguageModelProvider creates a http adapter based large language model provider instance
|
// NewCommonHttpLargeLanguageModelProvider creates a http adapter based large language model provider instance
|
||||||
func NewCommonHttpLargeLanguageModelProvider(llmConfig *settings.LLMConfig, adapter HttpLargeLanguageModelAdapter) *CommonHttpLargeLanguageModelProvider {
|
func NewCommonHttpLargeLanguageModelProvider(llmConfig *settings.LLMConfig, enableResponseLog bool, adapter HttpLargeLanguageModelAdapter) *CommonHttpLargeLanguageModelProvider {
|
||||||
return &CommonHttpLargeLanguageModelProvider{
|
return &CommonHttpLargeLanguageModelProvider{
|
||||||
adapter: adapter,
|
adapter: adapter,
|
||||||
httpClient: utils.NewHttpClient(llmConfig.LargeLanguageModelAPIRequestTimeout, llmConfig.LargeLanguageModelAPIProxy, llmConfig.LargeLanguageModelAPISkipTLSVerify, settings.GetUserAgent()),
|
httpClient: httpclient.NewHttpClient(llmConfig.LargeLanguageModelAPIRequestTimeout, llmConfig.LargeLanguageModelAPIProxy, llmConfig.LargeLanguageModelAPISkipTLSVerify, settings.GetUserAgent(), enableResponseLog),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,8 +159,8 @@ func (p *GoogleAILargeLanguageModelAdapter) buildJsonRequestBody(c core.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewGoogleAILargeLanguageModelProvider creates a new Google AI large language model provider instance
|
// NewGoogleAILargeLanguageModelProvider creates a new Google AI large language model provider instance
|
||||||
func NewGoogleAILargeLanguageModelProvider(llmConfig *settings.LLMConfig) provider.LargeLanguageModelProvider {
|
func NewGoogleAILargeLanguageModelProvider(llmConfig *settings.LLMConfig, enableResponseLog bool) provider.LargeLanguageModelProvider {
|
||||||
return common.NewCommonHttpLargeLanguageModelProvider(llmConfig, &GoogleAILargeLanguageModelAdapter{
|
return common.NewCommonHttpLargeLanguageModelProvider(llmConfig, enableResponseLog, &GoogleAILargeLanguageModelAdapter{
|
||||||
GoogleAIAPIKey: llmConfig.GoogleAIAPIKey,
|
GoogleAIAPIKey: llmConfig.GoogleAIAPIKey,
|
||||||
GoogleAIModelID: llmConfig.GoogleAIModelID,
|
GoogleAIModelID: llmConfig.GoogleAIModelID,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -158,8 +158,8 @@ func (p *OllamaLargeLanguageModelAdapter) getOllamaRequestUrl() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOllamaLargeLanguageModelProvider creates a new Ollama large language model provider instance
|
// NewOllamaLargeLanguageModelProvider creates a new Ollama large language model provider instance
|
||||||
func NewOllamaLargeLanguageModelProvider(llmConfig *settings.LLMConfig) provider.LargeLanguageModelProvider {
|
func NewOllamaLargeLanguageModelProvider(llmConfig *settings.LLMConfig, enableResponseLog bool) provider.LargeLanguageModelProvider {
|
||||||
return common.NewCommonHttpLargeLanguageModelProvider(llmConfig, &OllamaLargeLanguageModelAdapter{
|
return common.NewCommonHttpLargeLanguageModelProvider(llmConfig, enableResponseLog, &OllamaLargeLanguageModelAdapter{
|
||||||
OllamaServerURL: llmConfig.OllamaServerURL,
|
OllamaServerURL: llmConfig.OllamaServerURL,
|
||||||
OllamaModelID: llmConfig.OllamaModelID,
|
OllamaModelID: llmConfig.OllamaModelID,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ func (p *OpenAIOfficialChatCompletionsAPIProvider) GetModelID() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOpenAILargeLanguageModelProvider creates a new OpenAI large language model provider instance
|
// NewOpenAILargeLanguageModelProvider creates a new OpenAI large language model provider instance
|
||||||
func NewOpenAILargeLanguageModelProvider(llmConfig *settings.LLMConfig) provider.LargeLanguageModelProvider {
|
func NewOpenAILargeLanguageModelProvider(llmConfig *settings.LLMConfig, enableResponseLog bool) provider.LargeLanguageModelProvider {
|
||||||
return newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig, &OpenAIOfficialChatCompletionsAPIProvider{
|
return newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig, enableResponseLog, &OpenAIOfficialChatCompletionsAPIProvider{
|
||||||
OpenAIAPIKey: llmConfig.OpenAIAPIKey,
|
OpenAIAPIKey: llmConfig.OpenAIAPIKey,
|
||||||
OpenAIModelID: llmConfig.OpenAIModelID,
|
OpenAIModelID: llmConfig.OpenAIModelID,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -213,8 +213,8 @@ func (p *CommonOpenAIChatCompletionsAPILargeLanguageModelAdapter) buildJsonReque
|
|||||||
return requestBodyBytes, nil
|
return requestBodyBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig *settings.LLMConfig, apiProvider OpenAIChatCompletionsAPIProvider) provider.LargeLanguageModelProvider {
|
func newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig *settings.LLMConfig, enableResponseLog bool, apiProvider OpenAIChatCompletionsAPIProvider) provider.LargeLanguageModelProvider {
|
||||||
return common.NewCommonHttpLargeLanguageModelProvider(llmConfig, &CommonOpenAIChatCompletionsAPILargeLanguageModelAdapter{
|
return common.NewCommonHttpLargeLanguageModelProvider(llmConfig, enableResponseLog, &CommonOpenAIChatCompletionsAPILargeLanguageModelAdapter{
|
||||||
apiProvider: apiProvider,
|
apiProvider: apiProvider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ func (p *OpenAICompatibleChatCompletionsAPIProvider) getFinalChatCompletionsRequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOpenAICompatibleLargeLanguageModelProvider creates a new OpenAI compatible large language model provider instance
|
// NewOpenAICompatibleLargeLanguageModelProvider creates a new OpenAI compatible large language model provider instance
|
||||||
func NewOpenAICompatibleLargeLanguageModelProvider(llmConfig *settings.LLMConfig) provider.LargeLanguageModelProvider {
|
func NewOpenAICompatibleLargeLanguageModelProvider(llmConfig *settings.LLMConfig, enableResponseLog bool) provider.LargeLanguageModelProvider {
|
||||||
return newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig, &OpenAICompatibleChatCompletionsAPIProvider{
|
return newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig, enableResponseLog, &OpenAICompatibleChatCompletionsAPIProvider{
|
||||||
OpenAICompatibleBaseURL: llmConfig.OpenAICompatibleBaseURL,
|
OpenAICompatibleBaseURL: llmConfig.OpenAICompatibleBaseURL,
|
||||||
OpenAICompatibleAPIKey: llmConfig.OpenAICompatibleAPIKey,
|
OpenAICompatibleAPIKey: llmConfig.OpenAICompatibleAPIKey,
|
||||||
OpenAICompatibleModelID: llmConfig.OpenAICompatibleModelID,
|
OpenAICompatibleModelID: llmConfig.OpenAICompatibleModelID,
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ func (p *OpenRouterChatCompletionsAPIProvider) GetModelID() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOpenRouterLargeLanguageModelProvider creates a new OpenRouter large language model provider instance
|
// NewOpenRouterLargeLanguageModelProvider creates a new OpenRouter large language model provider instance
|
||||||
func NewOpenRouterLargeLanguageModelProvider(llmConfig *settings.LLMConfig) provider.LargeLanguageModelProvider {
|
func NewOpenRouterLargeLanguageModelProvider(llmConfig *settings.LLMConfig, enableResponseLog bool) provider.LargeLanguageModelProvider {
|
||||||
return newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig, &OpenRouterChatCompletionsAPIProvider{
|
return newCommonOpenAIChatCompletionsAPILargeLanguageModelAdapter(llmConfig, enableResponseLog, &OpenRouterChatCompletionsAPIProvider{
|
||||||
OpenRouterAPIKey: llmConfig.OpenRouterAPIKey,
|
OpenRouterAPIKey: llmConfig.OpenRouterAPIKey,
|
||||||
OpenRouterModelID: llmConfig.OpenRouterModelID,
|
OpenRouterModelID: llmConfig.OpenRouterModelID,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -305,6 +305,7 @@ type Config struct {
|
|||||||
EnableConsoleLog bool
|
EnableConsoleLog bool
|
||||||
EnableFileLog bool
|
EnableFileLog bool
|
||||||
|
|
||||||
|
EnableDebugLog bool
|
||||||
LogLevel Level
|
LogLevel Level
|
||||||
FileLogPath string
|
FileLogPath string
|
||||||
RequestFileLogPath string
|
RequestFileLogPath string
|
||||||
@@ -759,6 +760,12 @@ func loadLogConfiguration(config *Config, configFile *ini.File, sectionName stri
|
|||||||
return errs.ErrInvalidLogLevel
|
return errs.ErrInvalidLogLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.LogLevel == LOGLEVEL_DEBUG {
|
||||||
|
config.EnableDebugLog = true
|
||||||
|
} else {
|
||||||
|
config.EnableDebugLog = false
|
||||||
|
}
|
||||||
|
|
||||||
if config.EnableFileLog {
|
if config.EnableFileLog {
|
||||||
fileLogPath := getConfigItemStringValue(configFile, sectionName, "log_path")
|
fileLogPath := getConfigItemStringValue(configFile, sectionName, "log_path")
|
||||||
finalFileLogPath, _ := getFinalPath(config.WorkingPath, fileLogPath)
|
finalFileLogPath, _ := getFinalPath(config.WorkingPath, fileLogPath)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
|
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
|
"github.com/mayswind/ezbookkeeping/pkg/httpclient"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// WebDAVObjectStorage represents WebDAV object storage
|
// WebDAVObjectStorage represents WebDAV object storage
|
||||||
@@ -26,7 +26,7 @@ func NewWebDAVObjectStorage(config *settings.Config, pathPrefix string) (*WebDAV
|
|||||||
webDavConfig := config.WebDAVConfig
|
webDavConfig := config.WebDAVConfig
|
||||||
|
|
||||||
storage := &WebDAVObjectStorage{
|
storage := &WebDAVObjectStorage{
|
||||||
httpClient: utils.NewHttpClient(webDavConfig.RequestTimeout, webDavConfig.Proxy, webDavConfig.SkipTLSVerify, settings.GetUserAgent()),
|
httpClient: httpclient.NewHttpClient(webDavConfig.RequestTimeout, webDavConfig.Proxy, webDavConfig.SkipTLSVerify, settings.GetUserAgent(), false),
|
||||||
webDavConfig: webDavConfig,
|
webDavConfig: webDavConfig,
|
||||||
rootPath: webDavConfig.RootPath,
|
rootPath: webDavConfig.RootPath,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user