func event(serviceName string, methodName string, request proto.Message, response proto.Message, err error, duration time.Duration) *Call { call := &Call{ Service: serviceName, Method: methodName, Duration: prototime.DurationToProto(duration), } if request != nil { call.Request = request.String() } if response != nil { call.Response = response.String() } if err != nil { call.Error = err.Error() } return call }
func namespaceMod(m proto.Message, namespace string) { // pb.Query is the only type that has a name_space field. // All other namespace support in datastore is in the keys. switch m := m.(type) { case *pb.Query: if m.NameSpace == nil { m.NameSpace = &namespace } } }
func override(ctx context.Context, service, method string, in, out proto.Message) error { stats := ctx.Value(statsKey).(*requestStats) stats.wg.Add(1) defer stats.wg.Done() if service == "__go__" { return appengine.APICall(ctx, service, method, in, out) } // NOTE: This limits size of stack traces to 65KiB. b := make([]byte, 65536) i := runtime.Stack(b, false) stat := rpcStat{ Service: service, Method: method, Start: time.Now(), Offset: time.Since(stats.Start), StackData: string(b[0:i]), } err := appengine.APICall(ctx, service, method, in, out) stat.Duration = time.Since(stat.Start) stat.In = in.String() stat.Out = out.String() stat.Cost = getCost(out) if len(stat.In) > ProtoMaxBytes { stat.In = stat.In[:ProtoMaxBytes] + "..." } if len(stat.Out) > ProtoMaxBytes { stat.Out = stat.Out[:ProtoMaxBytes] + "..." } stats.lock.Lock() stats.RPCStats = append(stats.RPCStats, stat) stats.Cost += stat.Cost stats.lock.Unlock() return err }
func namespaceMod(m proto.Message, namespace string) { switch m := m.(type) { case *pb.MemcacheDeleteRequest: if m.NameSpace == nil { m.NameSpace = &namespace } case *pb.MemcacheGetRequest: if m.NameSpace == nil { m.NameSpace = &namespace } case *pb.MemcacheIncrementRequest: if m.NameSpace == nil { m.NameSpace = &namespace } case *pb.MemcacheSetRequest: if m.NameSpace == nil { m.NameSpace = &namespace } // MemcacheFlushRequest, MemcacheStatsRequest do not apply namespace. } }
func override(ctx context.Context, service, method string, in, out proto.Message) error { stats := stats(ctx) stats.wg.Add(1) defer stats.wg.Done() if service == "__go__" { return appengine.APICall(ctx, service, method, in, out) } stat := rpcStat{ Service: service, Method: method, Start: time.Now(), Offset: time.Since(stats.Start), StackData: string(debug.Stack()), } err := appengine.APICall(ctx, service, method, in, out) stat.Duration = time.Since(stat.Start) stat.In = in.String() stat.Out = out.String() stat.Cost = getCost(out) if len(stat.In) > ProtoMaxBytes { stat.In = stat.In[:ProtoMaxBytes] + "..." } if len(stat.Out) > ProtoMaxBytes { stat.Out = stat.Out[:ProtoMaxBytes] + "..." } stats.lock.Lock() stats.RPCStats = append(stats.RPCStats, stat) stats.Cost += stat.Cost stats.lock.Unlock() return err }
func returnProtoToPool(pool sync.Pool, p proto.Message) { p.Reset() pool.Put(p) }