Add opentracing Spans to the HTTP APIs (#270)

* Add opentracing Spans to the HTTP APIs

* Add opentracing spans to the HTTP RPC clients

* Set the span in the request context

* More docstring
This commit is contained in:
Mark Haines 2017-09-28 14:50:40 +01:00 committed by GitHub
parent 88dde65efc
commit c4947c2ffb
13 changed files with 152 additions and 57 deletions

View file

@ -53,7 +53,7 @@ func Setup(
) { ) {
apiMux.Handle("/_matrix/client/versions", apiMux.Handle("/_matrix/client/versions",
common.MakeAPI("versions", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("versions", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{ return util.JSONResponse{
Code: 200, Code: 200,
JSON: struct { JSON: struct {
@ -123,11 +123,11 @@ func Setup(
}), }),
).Methods("PUT", "OPTIONS") ).Methods("PUT", "OPTIONS")
r0mux.Handle("/register", common.MakeAPI("register", func(req *http.Request) util.JSONResponse { r0mux.Handle("/register", common.MakeExternalAPI("register", func(req *http.Request) util.JSONResponse {
return writers.Register(req, accountDB, deviceDB, &cfg) return writers.Register(req, accountDB, deviceDB, &cfg)
})).Methods("POST", "OPTIONS") })).Methods("POST", "OPTIONS")
v1mux.Handle("/register", common.MakeAPI("register", func(req *http.Request) util.JSONResponse { v1mux.Handle("/register", common.MakeExternalAPI("register", func(req *http.Request) util.JSONResponse {
return writers.LegacyRegister(req, accountDB, deviceDB, &cfg) return writers.LegacyRegister(req, accountDB, deviceDB, &cfg)
})).Methods("POST", "OPTIONS") })).Methods("POST", "OPTIONS")
@ -161,13 +161,13 @@ func Setup(
// Stub endpoints required by Riot // Stub endpoints required by Riot
r0mux.Handle("/login", r0mux.Handle("/login",
common.MakeAPI("login", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("login", func(req *http.Request) util.JSONResponse {
return readers.Login(req, accountDB, deviceDB, cfg) return readers.Login(req, accountDB, deviceDB, cfg)
}), }),
).Methods("GET", "POST", "OPTIONS") ).Methods("GET", "POST", "OPTIONS")
r0mux.Handle("/pushrules/", r0mux.Handle("/pushrules/",
common.MakeAPI("push_rules", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("push_rules", func(req *http.Request) util.JSONResponse {
// TODO: Implement push rules API // TODO: Implement push rules API
res := json.RawMessage(`{ res := json.RawMessage(`{
"global": { "global": {
@ -186,7 +186,7 @@ func Setup(
).Methods("GET") ).Methods("GET")
r0mux.Handle("/user/{userID}/filter", r0mux.Handle("/user/{userID}/filter",
common.MakeAPI("make_filter", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("make_filter", func(req *http.Request) util.JSONResponse {
// TODO: Persist filter and return filter ID // TODO: Persist filter and return filter ID
return util.JSONResponse{ return util.JSONResponse{
Code: 200, Code: 200,
@ -196,7 +196,7 @@ func Setup(
).Methods("POST", "OPTIONS") ).Methods("POST", "OPTIONS")
r0mux.Handle("/user/{userID}/filter/{filterID}", r0mux.Handle("/user/{userID}/filter/{filterID}",
common.MakeAPI("filter", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("filter", func(req *http.Request) util.JSONResponse {
// TODO: Retrieve filter based on ID // TODO: Retrieve filter based on ID
return util.JSONResponse{ return util.JSONResponse{
Code: 200, Code: 200,
@ -208,14 +208,14 @@ func Setup(
// Riot user settings // Riot user settings
r0mux.Handle("/profile/{userID}", r0mux.Handle("/profile/{userID}",
common.MakeAPI("profile", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("profile", func(req *http.Request) util.JSONResponse {
vars := mux.Vars(req) vars := mux.Vars(req)
return readers.GetProfile(req, accountDB, vars["userID"]) return readers.GetProfile(req, accountDB, vars["userID"])
}), }),
).Methods("GET") ).Methods("GET")
r0mux.Handle("/profile/{userID}/avatar_url", r0mux.Handle("/profile/{userID}/avatar_url",
common.MakeAPI("profile_avatar_url", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("profile_avatar_url", func(req *http.Request) util.JSONResponse {
vars := mux.Vars(req) vars := mux.Vars(req)
return readers.GetAvatarURL(req, accountDB, vars["userID"]) return readers.GetAvatarURL(req, accountDB, vars["userID"])
}), }),
@ -231,7 +231,7 @@ func Setup(
// PUT requests, so we need to allow this method // PUT requests, so we need to allow this method
r0mux.Handle("/profile/{userID}/displayname", r0mux.Handle("/profile/{userID}/displayname",
common.MakeAPI("profile_displayname", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("profile_displayname", func(req *http.Request) util.JSONResponse {
vars := mux.Vars(req) vars := mux.Vars(req)
return readers.GetDisplayName(req, accountDB, vars["userID"]) return readers.GetDisplayName(req, accountDB, vars["userID"])
}), }),
@ -265,14 +265,14 @@ func Setup(
).Methods("POST", "OPTIONS") ).Methods("POST", "OPTIONS")
r0mux.Handle("/{path:(?:account/3pid|register)}/email/requestToken", r0mux.Handle("/{path:(?:account/3pid|register)}/email/requestToken",
common.MakeAPI("account_3pid_request_token", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("account_3pid_request_token", func(req *http.Request) util.JSONResponse {
return readers.RequestEmailToken(req, accountDB, cfg) return readers.RequestEmailToken(req, accountDB, cfg)
}), }),
).Methods("POST", "OPTIONS") ).Methods("POST", "OPTIONS")
// Riot logs get flooded unless this is handled // Riot logs get flooded unless this is handled
r0mux.Handle("/presence/{userID}/status", r0mux.Handle("/presence/{userID}/status",
common.MakeAPI("presence", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("presence", func(req *http.Request) util.JSONResponse {
// TODO: Set presence (probably the responsibility of a presence server not clientapi) // TODO: Set presence (probably the responsibility of a presence server not clientapi)
return util.JSONResponse{ return util.JSONResponse{
Code: 200, Code: 200,
@ -282,7 +282,7 @@ func Setup(
).Methods("PUT", "OPTIONS") ).Methods("PUT", "OPTIONS")
r0mux.Handle("/voip/turnServer", r0mux.Handle("/voip/turnServer",
common.MakeAPI("turn_server", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("turn_server", func(req *http.Request) util.JSONResponse {
// TODO: Return credentials for a turn server if one is configured. // TODO: Return credentials for a turn server if one is configured.
return util.JSONResponse{ return util.JSONResponse{
Code: 200, Code: 200,
@ -292,7 +292,7 @@ func Setup(
).Methods("GET") ).Methods("GET")
unstableMux.Handle("/thirdparty/protocols", unstableMux.Handle("/thirdparty/protocols",
common.MakeAPI("thirdparty_protocols", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("thirdparty_protocols", func(req *http.Request) util.JSONResponse {
// TODO: Return the third party protcols // TODO: Return the third party protcols
return util.JSONResponse{ return util.JSONResponse{
Code: 200, Code: 200,
@ -302,7 +302,7 @@ func Setup(
).Methods("GET") ).Methods("GET")
r0mux.Handle("/rooms/{roomID}/initialSync", r0mux.Handle("/rooms/{roomID}/initialSync",
common.MakeAPI("rooms_initial_sync", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("rooms_initial_sync", func(req *http.Request) util.JSONResponse {
// TODO: Allow people to peek into rooms. // TODO: Allow people to peek into rooms.
return util.JSONResponse{ return util.JSONResponse{
Code: 403, Code: 403,
@ -340,14 +340,14 @@ func Setup(
).Methods("GET") ).Methods("GET")
r0mux.Handle("/rooms/{roomID}/read_markers", r0mux.Handle("/rooms/{roomID}/read_markers",
common.MakeAPI("rooms_read_markers", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("rooms_read_markers", func(req *http.Request) util.JSONResponse {
// TODO: return the read_markers. // TODO: return the read_markers.
return util.JSONResponse{Code: 200, JSON: struct{}{}} return util.JSONResponse{Code: 200, JSON: struct{}{}}
}), }),
).Methods("POST", "OPTIONS") ).Methods("POST", "OPTIONS")
r0mux.Handle("/rooms/{roomID}/typing/{userID}", r0mux.Handle("/rooms/{roomID}/typing/{userID}",
common.MakeAPI("rooms_typing", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("rooms_typing", func(req *http.Request) util.JSONResponse {
// TODO: handling typing // TODO: handling typing
return util.JSONResponse{Code: 200, JSON: struct{}{}} return util.JSONResponse{Code: 200, JSON: struct{}{}}
}), }),
@ -355,7 +355,7 @@ func Setup(
// Stub implementations for sytest // Stub implementations for sytest
r0mux.Handle("/events", r0mux.Handle("/events",
common.MakeAPI("events", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("events", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{Code: 200, JSON: map[string]interface{}{ return util.JSONResponse{Code: 200, JSON: map[string]interface{}{
"chunk": []interface{}{}, "chunk": []interface{}{},
"start": "", "start": "",
@ -365,7 +365,7 @@ func Setup(
).Methods("GET") ).Methods("GET")
r0mux.Handle("/initialSync", r0mux.Handle("/initialSync",
common.MakeAPI("initial_sync", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("initial_sync", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{Code: 200, JSON: map[string]interface{}{ return util.JSONResponse{Code: 200, JSON: map[string]interface{}{
"end": "", "end": "",
}} }}

View file

@ -20,6 +20,7 @@ import (
"os" "os"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/config"
"github.com/matrix-org/dendrite/mediaapi/routing" "github.com/matrix-org/dendrite/mediaapi/routing"
@ -52,12 +53,17 @@ func main() {
log.WithError(err).Panic("Failed to open database") log.WithError(err).Panic("Failed to open database")
} }
deviceDB, err := devices.NewDatabase(string(cfg.Database.Device), cfg.Matrix.ServerName)
if err != nil {
log.WithError(err).Panicf("Failed to setup device database(%q)", cfg.Database.Device)
}
client := gomatrixserverlib.NewClient() client := gomatrixserverlib.NewClient()
log.Info("Starting media API server on ", cfg.Listen.MediaAPI) log.Info("Starting media API server on ", cfg.Listen.MediaAPI)
api := mux.NewRouter() api := mux.NewRouter()
routing.Setup(api, cfg, db, client) routing.Setup(api, cfg, db, deviceDB, client)
common.SetupHTTPAPI(http.DefaultServeMux, api) common.SetupHTTPAPI(http.DefaultServeMux, api)
log.Fatal(http.ListenAndServe(string(cfg.Listen.MediaAPI), nil)) log.Fatal(http.ListenAndServe(string(cfg.Listen.MediaAPI), nil))

View file

@ -325,7 +325,7 @@ func (m *monolith) setupAPIs() {
) )
mediaapi_routing.Setup( mediaapi_routing.Setup(
m.api, m.cfg, m.mediaAPIDB, &m.federation.Client, m.api, m.cfg, m.mediaAPIDB, m.deviceDB, &m.federation.Client,
) )
syncapi_routing.Setup(m.api, syncapi_sync.NewRequestPool( syncapi_routing.Setup(m.api, syncapi_sync.NewRequestPool(

View file

@ -9,6 +9,8 @@ import (
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
opentracing "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -21,13 +23,47 @@ func MakeAuthAPI(metricsName string, deviceDB auth.DeviceDatabase, f func(*http.
} }
return f(req, device) return f(req, device)
} }
return MakeAPI(metricsName, h) return MakeExternalAPI(metricsName, h)
} }
// MakeAPI turns a util.JSONRequestHandler function into an http.Handler. // MakeExternalAPI turns a util.JSONRequestHandler function into an http.Handler.
func MakeAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.Handler { // This is used for APIs that are called from the internet.
h := util.NewJSONRequestHandler(f) func MakeExternalAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.Handler {
return prometheus.InstrumentHandler(metricsName, util.MakeJSONAPI(h)) h := util.MakeJSONAPI(util.NewJSONRequestHandler(f))
withSpan := func(w http.ResponseWriter, req *http.Request) {
span := opentracing.StartSpan(metricsName)
defer span.Finish()
req = req.WithContext(opentracing.ContextWithSpan(req.Context(), span))
h.ServeHTTP(w, req)
}
return prometheus.InstrumentHandler(metricsName, http.HandlerFunc(withSpan))
}
// MakeInternalAPI turns a util.JSONRequestHandler function into an http.Handler.
// This is used for APIs that are internal to dendrite.
// If we are passed a tracing context in the request headers then we use that
// as the parent of any tracing spans we create.
func MakeInternalAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.Handler {
h := util.MakeJSONAPI(util.NewJSONRequestHandler(f))
withSpan := func(w http.ResponseWriter, req *http.Request) {
carrier := opentracing.HTTPHeadersCarrier(req.Header)
tracer := opentracing.GlobalTracer()
clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
var span opentracing.Span
if err == nil {
// Default to a span without RPC context.
span = tracer.StartSpan(metricsName)
} else {
// Set the RPC context.
span = tracer.StartSpan(metricsName, ext.RPCServerOption(clientContext))
}
defer span.Finish()
req = req.WithContext(opentracing.ContextWithSpan(req.Context(), span))
h.ServeHTTP(w, req)
}
return prometheus.InstrumentHandler(metricsName, http.HandlerFunc(withSpan))
} }
// MakeFedAPI makes an http.Handler that checks matrix federation authentication. // MakeFedAPI makes an http.Handler that checks matrix federation authentication.
@ -46,7 +82,7 @@ func MakeFedAPI(
} }
return f(req, fedReq) return f(req, fedReq)
} }
return MakeAPI(metricsName, h) return MakeExternalAPI(metricsName, h)
} }
// SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics // SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics

View file

@ -48,7 +48,7 @@ func Setup(
v2keysmux := apiMux.PathPrefix(pathPrefixV2Keys).Subrouter() v2keysmux := apiMux.PathPrefix(pathPrefixV2Keys).Subrouter()
v1fedmux := apiMux.PathPrefix(pathPrefixV1Federation).Subrouter() v1fedmux := apiMux.PathPrefix(pathPrefixV1Federation).Subrouter()
localKeys := common.MakeAPI("localkeys", func(req *http.Request) util.JSONResponse { localKeys := common.MakeExternalAPI("localkeys", func(req *http.Request) util.JSONResponse {
return readers.LocalKeys(cfg) return readers.LocalKeys(cfg)
}) })
@ -81,7 +81,7 @@ func Setup(
}, },
)).Methods("PUT", "OPTIONS") )).Methods("PUT", "OPTIONS")
v1fedmux.Handle("/3pid/onbind", common.MakeAPI("3pid_onbind", v1fedmux.Handle("/3pid/onbind", common.MakeExternalAPI("3pid_onbind",
func(req *http.Request) util.JSONResponse { func(req *http.Request) util.JSONResponse {
return writers.CreateInvitesFrom3PIDInvites(req, query, cfg, producer, federation, accountDB) return writers.CreateInvitesFrom3PIDInvites(req, query, cfg, producer, federation, accountDB)
}, },
@ -107,7 +107,7 @@ func Setup(
}, },
)).Methods("GET") )).Methods("GET")
v1fedmux.Handle("/version", common.MakeAPI( v1fedmux.Handle("/version", common.MakeExternalAPI(
"federation_version", "federation_version",
func(httpReq *http.Request) util.JSONResponse { func(httpReq *http.Request) util.JSONResponse {
return readers.Version() return readers.Version()

View file

@ -17,7 +17,10 @@ package routing
import ( import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/config"
"github.com/matrix-org/dendrite/mediaapi/storage" "github.com/matrix-org/dendrite/mediaapi/storage"
@ -35,6 +38,7 @@ func Setup(
apiMux *mux.Router, apiMux *mux.Router,
cfg *config.Dendrite, cfg *config.Dendrite,
db *storage.Database, db *storage.Database,
deviceDB *devices.Database,
client *gomatrixserverlib.Client, client *gomatrixserverlib.Client,
) { ) {
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter() r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
@ -43,10 +47,13 @@ func Setup(
PathToResult: map[string]*types.ThumbnailGenerationResult{}, PathToResult: map[string]*types.ThumbnailGenerationResult{},
} }
// FIXME: /upload should use common.MakeAuthAPI() r0mux.Handle("/upload", common.MakeAuthAPI(
r0mux.Handle("/upload", common.MakeAPI("upload", func(req *http.Request) util.JSONResponse { "upload",
return writers.Upload(req, cfg, db, activeThumbnailGeneration) deviceDB,
})).Methods("POST", "OPTIONS") func(req *http.Request, _ *authtypes.Device) util.JSONResponse {
return writers.Upload(req, cfg, db, activeThumbnailGeneration)
},
)).Methods("POST", "OPTIONS")
activeRemoteRequests := &types.ActiveRemoteRequests{ activeRemoteRequests := &types.ActiveRemoteRequests{
MXCToResult: map[string]*types.RemoteRequestResult{}, MXCToResult: map[string]*types.RemoteRequestResult{},

View file

@ -32,7 +32,7 @@ const pathPrefixR0 = "/_matrix/client/r0"
func Setup(apiMux *mux.Router, deviceDB *devices.Database, publicRoomsDB *storage.PublicRoomsServerDatabase) { func Setup(apiMux *mux.Router, deviceDB *devices.Database, publicRoomsDB *storage.PublicRoomsServerDatabase) {
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter() r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
r0mux.Handle("/directory/list/room/{roomID}", r0mux.Handle("/directory/list/room/{roomID}",
common.MakeAPI("directory_list", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("directory_list", func(req *http.Request) util.JSONResponse {
vars := mux.Vars(req) vars := mux.Vars(req)
return directory.GetVisibility(req, publicRoomsDB, vars["roomID"]) return directory.GetVisibility(req, publicRoomsDB, vars["roomID"])
}), }),
@ -44,7 +44,7 @@ func Setup(apiMux *mux.Router, deviceDB *devices.Database, publicRoomsDB *storag
}), }),
).Methods("PUT", "OPTIONS") ).Methods("PUT", "OPTIONS")
r0mux.Handle("/publicRooms", r0mux.Handle("/publicRooms",
common.MakeAPI("public_rooms", func(req *http.Request) util.JSONResponse { common.MakeExternalAPI("public_rooms", func(req *http.Request) util.JSONResponse {
return directory.GetPublicRooms(req, publicRoomsDB) return directory.GetPublicRooms(req, publicRoomsDB)
}), }),
).Methods("GET", "POST", "OPTIONS") ).Methods("GET", "POST", "OPTIONS")

View file

@ -224,7 +224,7 @@ func (r *RoomserverAliasAPI) sendUpdatedAliasesEvent(
func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) { func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
servMux.Handle( servMux.Handle(
api.RoomserverSetRoomAliasPath, api.RoomserverSetRoomAliasPath,
common.MakeAPI("setRoomAlias", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("setRoomAlias", func(req *http.Request) util.JSONResponse {
var request api.SetRoomAliasRequest var request api.SetRoomAliasRequest
var response api.SetRoomAliasResponse var response api.SetRoomAliasResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -238,7 +238,7 @@ func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
) )
servMux.Handle( servMux.Handle(
api.RoomserverGetAliasRoomIDPath, api.RoomserverGetAliasRoomIDPath,
common.MakeAPI("getAliasRoomID", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("getAliasRoomID", func(req *http.Request) util.JSONResponse {
var request api.GetAliasRoomIDRequest var request api.GetAliasRoomIDRequest
var response api.GetAliasRoomIDResponse var response api.GetAliasRoomIDResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -252,7 +252,7 @@ func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
) )
servMux.Handle( servMux.Handle(
api.RoomserverRemoveRoomAliasPath, api.RoomserverRemoveRoomAliasPath,
common.MakeAPI("removeRoomAlias", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("removeRoomAlias", func(req *http.Request) util.JSONResponse {
var request api.RemoveRoomAliasRequest var request api.RemoveRoomAliasRequest
var response api.RemoveRoomAliasResponse var response api.RemoveRoomAliasResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {

View file

@ -17,6 +17,8 @@ package api
import ( import (
"context" "context"
"net/http" "net/http"
opentracing "github.com/opentracing/opentracing-go"
) )
// SetRoomAliasRequest is a request to SetRoomAlias // SetRoomAliasRequest is a request to SetRoomAlias
@ -111,8 +113,11 @@ func (h *httpRoomserverAliasAPI) SetRoomAlias(
request *SetRoomAliasRequest, request *SetRoomAliasRequest,
response *SetRoomAliasResponse, response *SetRoomAliasResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "SetRoomAlias")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverSetRoomAliasPath apiURL := h.roomserverURL + RoomserverSetRoomAliasPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// GetAliasRoomID implements RoomserverAliasAPI // GetAliasRoomID implements RoomserverAliasAPI
@ -121,8 +126,11 @@ func (h *httpRoomserverAliasAPI) GetAliasRoomID(
request *GetAliasRoomIDRequest, request *GetAliasRoomIDRequest,
response *GetAliasRoomIDResponse, response *GetAliasRoomIDResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "GetAliasRoomID")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverGetAliasRoomIDPath apiURL := h.roomserverURL + RoomserverGetAliasRoomIDPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// RemoveRoomAlias implements RoomserverAliasAPI // RemoveRoomAlias implements RoomserverAliasAPI
@ -131,6 +139,9 @@ func (h *httpRoomserverAliasAPI) RemoveRoomAlias(
request *RemoveRoomAliasRequest, request *RemoveRoomAliasRequest,
response *RemoveRoomAliasResponse, response *RemoveRoomAliasResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "RemoveRoomAlias")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverRemoveRoomAliasPath apiURL := h.roomserverURL + RoomserverRemoveRoomAliasPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }

View file

@ -20,6 +20,7 @@ import (
"net/http" "net/http"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
opentracing "github.com/opentracing/opentracing-go"
) )
const ( const (
@ -117,6 +118,9 @@ func (h *httpRoomserverInputAPI) InputRoomEvents(
request *InputRoomEventsRequest, request *InputRoomEventsRequest,
response *InputRoomEventsResponse, response *InputRoomEventsResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "InputRoomEvents")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverInputRoomEventsPath apiURL := h.roomserverURL + RoomserverInputRoomEventsPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }

View file

@ -21,6 +21,10 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
@ -234,8 +238,11 @@ func (h *httpRoomserverQueryAPI) QueryLatestEventsAndState(
request *QueryLatestEventsAndStateRequest, request *QueryLatestEventsAndStateRequest,
response *QueryLatestEventsAndStateResponse, response *QueryLatestEventsAndStateResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryLatestEventsAndState")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverQueryLatestEventsAndStatePath apiURL := h.roomserverURL + RoomserverQueryLatestEventsAndStatePath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// QueryStateAfterEvents implements RoomserverQueryAPI // QueryStateAfterEvents implements RoomserverQueryAPI
@ -244,8 +251,11 @@ func (h *httpRoomserverQueryAPI) QueryStateAfterEvents(
request *QueryStateAfterEventsRequest, request *QueryStateAfterEventsRequest,
response *QueryStateAfterEventsResponse, response *QueryStateAfterEventsResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryStateAfterEvents")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverQueryStateAfterEventsPath apiURL := h.roomserverURL + RoomserverQueryStateAfterEventsPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// QueryEventsByID implements RoomserverQueryAPI // QueryEventsByID implements RoomserverQueryAPI
@ -254,8 +264,11 @@ func (h *httpRoomserverQueryAPI) QueryEventsByID(
request *QueryEventsByIDRequest, request *QueryEventsByIDRequest,
response *QueryEventsByIDResponse, response *QueryEventsByIDResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryEventsByID")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverQueryEventsByIDPath apiURL := h.roomserverURL + RoomserverQueryEventsByIDPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// QueryMembershipsForRoom implements RoomserverQueryAPI // QueryMembershipsForRoom implements RoomserverQueryAPI
@ -264,8 +277,11 @@ func (h *httpRoomserverQueryAPI) QueryMembershipsForRoom(
request *QueryMembershipsForRoomRequest, request *QueryMembershipsForRoomRequest,
response *QueryMembershipsForRoomResponse, response *QueryMembershipsForRoomResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryMembershipsForRoom")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverQueryMembershipsForRoomPath apiURL := h.roomserverURL + RoomserverQueryMembershipsForRoomPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// QueryInvitesForUser implements RoomserverQueryAPI // QueryInvitesForUser implements RoomserverQueryAPI
@ -274,8 +290,11 @@ func (h *httpRoomserverQueryAPI) QueryInvitesForUser(
request *QueryInvitesForUserRequest, request *QueryInvitesForUserRequest,
response *QueryInvitesForUserResponse, response *QueryInvitesForUserResponse,
) error { ) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryInvitesForUser")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverQueryInvitesForUserPath apiURL := h.roomserverURL + RoomserverQueryInvitesForUserPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// QueryServerAllowedToSeeEvent implements RoomserverQueryAPI // QueryServerAllowedToSeeEvent implements RoomserverQueryAPI
@ -284,12 +303,15 @@ func (h *httpRoomserverQueryAPI) QueryServerAllowedToSeeEvent(
request *QueryServerAllowedToSeeEventRequest, request *QueryServerAllowedToSeeEventRequest,
response *QueryServerAllowedToSeeEventResponse, response *QueryServerAllowedToSeeEventResponse,
) (err error) { ) (err error) {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerAllowedToSeeEvent")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverQueryServerAllowedToSeeEventPath apiURL := h.roomserverURL + RoomserverQueryServerAllowedToSeeEventPath
return postJSON(ctx, h.httpClient, apiURL, request, response) return postJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
func postJSON( func postJSON(
ctx context.Context, httpClient *http.Client, ctx context.Context, span opentracing.Span, httpClient *http.Client,
apiURL string, request, response interface{}, apiURL string, request, response interface{},
) error { ) error {
jsonBytes, err := json.Marshal(request) jsonBytes, err := json.Marshal(request)
@ -302,6 +324,15 @@ func postJSON(
return err return err
} }
// Mark the span as being an RPC client.
ext.SpanKindRPCClient.Set(span)
carrier := opentracing.HTTPHeadersCarrier(req.Header)
tracer := opentracing.GlobalTracer()
if err = tracer.Inject(span.Context(), opentracing.HTTPHeaders, carrier); err != nil {
return err
}
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
res, err := httpClient.Do(req.WithContext(ctx)) res, err := httpClient.Do(req.WithContext(ctx))

View file

@ -74,7 +74,7 @@ func (r *RoomserverInputAPI) InputRoomEvents(
// SetupHTTP adds the RoomserverInputAPI handlers to the http.ServeMux. // SetupHTTP adds the RoomserverInputAPI handlers to the http.ServeMux.
func (r *RoomserverInputAPI) SetupHTTP(servMux *http.ServeMux) { func (r *RoomserverInputAPI) SetupHTTP(servMux *http.ServeMux) {
servMux.Handle(api.RoomserverInputRoomEventsPath, servMux.Handle(api.RoomserverInputRoomEventsPath,
common.MakeAPI("inputRoomEvents", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("inputRoomEvents", func(req *http.Request) util.JSONResponse {
var request api.InputRoomEventsRequest var request api.InputRoomEventsRequest
var response api.InputRoomEventsResponse var response api.InputRoomEventsResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {

View file

@ -423,7 +423,7 @@ func (r *RoomserverQueryAPI) QueryServerAllowedToSeeEvent(
func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) { func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
servMux.Handle( servMux.Handle(
api.RoomserverQueryLatestEventsAndStatePath, api.RoomserverQueryLatestEventsAndStatePath,
common.MakeAPI("queryLatestEventsAndState", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("queryLatestEventsAndState", func(req *http.Request) util.JSONResponse {
var request api.QueryLatestEventsAndStateRequest var request api.QueryLatestEventsAndStateRequest
var response api.QueryLatestEventsAndStateResponse var response api.QueryLatestEventsAndStateResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -437,7 +437,7 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
) )
servMux.Handle( servMux.Handle(
api.RoomserverQueryStateAfterEventsPath, api.RoomserverQueryStateAfterEventsPath,
common.MakeAPI("queryStateAfterEvents", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("queryStateAfterEvents", func(req *http.Request) util.JSONResponse {
var request api.QueryStateAfterEventsRequest var request api.QueryStateAfterEventsRequest
var response api.QueryStateAfterEventsResponse var response api.QueryStateAfterEventsResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -451,7 +451,7 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
) )
servMux.Handle( servMux.Handle(
api.RoomserverQueryEventsByIDPath, api.RoomserverQueryEventsByIDPath,
common.MakeAPI("queryEventsByID", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("queryEventsByID", func(req *http.Request) util.JSONResponse {
var request api.QueryEventsByIDRequest var request api.QueryEventsByIDRequest
var response api.QueryEventsByIDResponse var response api.QueryEventsByIDResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -465,7 +465,7 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
) )
servMux.Handle( servMux.Handle(
api.RoomserverQueryMembershipsForRoomPath, api.RoomserverQueryMembershipsForRoomPath,
common.MakeAPI("queryMembershipsForRoom", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("queryMembershipsForRoom", func(req *http.Request) util.JSONResponse {
var request api.QueryMembershipsForRoomRequest var request api.QueryMembershipsForRoomRequest
var response api.QueryMembershipsForRoomResponse var response api.QueryMembershipsForRoomResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -479,7 +479,7 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
) )
servMux.Handle( servMux.Handle(
api.RoomserverQueryInvitesForUserPath, api.RoomserverQueryInvitesForUserPath,
common.MakeAPI("queryInvitesForUser", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("queryInvitesForUser", func(req *http.Request) util.JSONResponse {
var request api.QueryInvitesForUserRequest var request api.QueryInvitesForUserRequest
var response api.QueryInvitesForUserResponse var response api.QueryInvitesForUserResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -493,7 +493,7 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
) )
servMux.Handle( servMux.Handle(
api.RoomserverQueryServerAllowedToSeeEventPath, api.RoomserverQueryServerAllowedToSeeEventPath,
common.MakeAPI("queryServerAllowedToSeeEvent", func(req *http.Request) util.JSONResponse { common.MakeInternalAPI("queryServerAllowedToSeeEvent", func(req *http.Request) util.JSONResponse {
var request api.QueryServerAllowedToSeeEventRequest var request api.QueryServerAllowedToSeeEventRequest
var response api.QueryServerAllowedToSeeEventResponse var response api.QueryServerAllowedToSeeEventResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {