public TupleList <decimal, Metric> CalculateMetrics <TCurrent>(List <TCurrent> telemetryTuples) where TCurrent : ITelemetry { var result = new TupleList <decimal, Metric>(); var totalRequestRate = telemetryTuples .Where(t => t.MetricName.Equals(MetricConstants.TotalRequestsMetricName, StringComparison.OrdinalIgnoreCase)) .Select( t => { var newMetric = new Tuple <decimal, Metric>( Math.Round((t.Value * 60) / monitoringIntervalInSeconds, 3), TotalRequestsRateMetric); return(newMetric); }); result.AddRange(totalRequestRate); var failedRequestRate = telemetryTuples .Where(t => t.MetricName.Equals(MetricConstants.FailedRequestsMetricName, StringComparison.OrdinalIgnoreCase)) .Select( t => { var newMetric = new Tuple <decimal, Metric>( Math.Round((t.Value * 60) / monitoringIntervalInSeconds, 3), FailedRequestsRateMetric); return(newMetric); }); result.AddRange(failedRequestRate); return(result); }
public TupleList <decimal, Metric> CalculateMetrics <TCurrent>(List <TCurrent> telemetry) where TCurrent : ITelemetry { var result = new TupleList <decimal, Metric>(); var totalRequests = telemetry.FirstOrDefault(t => t.MetricName.Equals(MetricConstants.TotalRequestsMetricName, StringComparison.OrdinalIgnoreCase)); if (totalRequests != null) { var totalRequestsCount = totalRequests.Value; result.AddRange( telemetry .Where(t => Regex.IsMatch(t.MetricName, MetricConstants.HttpStatusCodeReqeustsMetricRegularExpression, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)) .Select( t => { decimal value = 0; if (totalRequestsCount != 0) { value = Math.Round(t.Value * 100 / totalRequestsCount, 3); } var newMetric = new Tuple <decimal, Metric>( value, GetHttpStatusCodeRatioMetric(t.MetricName)); return(newMetric); })); } return(result); }
private TupleList <TCurrent, Metric> GenerateMetrics <TCurrent>( MetricType type, List <TCurrent> telemetry, Func <string, DateTime, Metric, decimal, TCurrent> createNewMetric) where TCurrent : ITelemetry { var calculatedMetrics = new TupleList <TCurrent, Metric>(); var filteredStrategies = strategies.Where(s => s.Type == type).ToArray(); var telemetryGroups = telemetry.GroupBy(t => t.GroupId); foreach (var telemetryGroup in telemetryGroups) { var allMetrics = telemetryGroup.ToList(); var timestamp = allMetrics.First().Timestamp; foreach (var strategy in filteredStrategies) { var newMetricValueTuples = strategy.CalculateMetrics(allMetrics); var newMetrics = newMetricValueTuples.Select( nmvt => new Tuple <TCurrent, Metric>( createNewMetric(telemetryGroup.Key, timestamp, nmvt.Item2, nmvt.Item1), nmvt.Item2)); allMetrics.AddRange(newMetrics.Select(nmvt => nmvt.Item1)); calculatedMetrics.AddRange(newMetrics); } } return(calculatedMetrics); }
public void SubmitsTraces(string packageVersion) { using var telemetry = this.ConfigureTelemetry(); using (var agent = EnvironmentHelper.GetMockAgent()) using (RunSampleAndWaitForExit(agent, arguments: $"{TestPrefix}", packageVersion: packageVersion)) { // note: ignore the INFO command because it's timing is unpredictable (on Linux?) var spans = agent.WaitForSpans(11) .Where(s => s.Type == "redis" && s.Resource != "INFO" && s.Resource != "ROLE" && s.Resource != "QUIT") .OrderBy(s => s.Start) .ToList(); var host = Environment.GetEnvironmentVariable("SERVICESTACK_REDIS_HOST") ?? "localhost:6379"; var port = host.Substring(host.IndexOf(':') + 1); host = host.Substring(0, host.IndexOf(':')); foreach (var span in spans) { Assert.Equal("redis.command", span.Name); Assert.Equal("Samples.ServiceStack.Redis-redis", span.Service); Assert.Equal(SpanTypes.Redis, span.Type); Assert.Equal(host, DictionaryExtensions.GetValueOrDefault(span.Tags, "out.host")); Assert.Equal(port, DictionaryExtensions.GetValueOrDefault(span.Tags, "out.port")); Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag."); } var expectedFromOneRun = new TupleList <string, string> { { "SET", $"SET {TestPrefix}ServiceStack.Redis.INCR 0" }, { "PING", "PING" }, { "DDCUSTOM", "DDCUSTOM COMMAND" }, { "ECHO", "ECHO Hello World" }, { "SLOWLOG", "SLOWLOG GET 5" }, { "INCR", $"INCR {TestPrefix}ServiceStack.Redis.INCR" }, { "INCRBYFLOAT", $"INCRBYFLOAT {TestPrefix}ServiceStack.Redis.INCR 1.25" }, { "TIME", "TIME" }, { "SELECT", "SELECT 0" }, }; var expected = new TupleList <string, string>(); expected.AddRange(expectedFromOneRun); expected.AddRange(expectedFromOneRun); #if NETCOREAPP3_1 || NET5_0 expected.AddRange(expectedFromOneRun); // On .NET Core 3.1 and .NET 5 we run the routine a third time #endif Assert.Equal(expected.Count, spans.Count); for (int i = 0; i < expected.Count; i++) { var e1 = expected[i].Item1; var e2 = expected[i].Item2; var a1 = i < spans.Count ? spans[i].Resource : string.Empty; var a2 = i < spans.Count ? DictionaryExtensions.GetValueOrDefault(spans[i].Tags, "redis.raw_command") : string.Empty; Assert.True(e1 == a1, $@"invalid resource name for span #{i}, expected ""{e1}"", actual ""{a1}"""); Assert.True(e2 == a2, $@"invalid raw command for span #{i}, expected ""{e2}"" != ""{a2}"""); } telemetry.AssertIntegrationEnabled(IntegrationId.ServiceStackRedis); } }
public void SubmitsTraces() { int agentPort = TcpPortProvider.GetOpenPort(); using (var agent = new MockTracerAgent(agentPort)) using (var processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"StackExchange {TestPrefix}")) { Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}"); var expected = new TupleList <string, string> { { "SET", $"SET {TestPrefix}StackExchange.Redis.INCR" }, { "PING", "PING" }, { "DDCUSTOM", "DDCUSTOM" }, { "ECHO", "ECHO" }, { "SLOWLOG", "SLOWLOG" }, { "INCR", $"INCR {TestPrefix}StackExchange.Redis.INCR" }, { "INCRBYFLOAT", $"INCRBYFLOAT {TestPrefix}StackExchange.Redis.INCR" }, { "GET", $"GET {TestPrefix}StackExchange.Redis.INCR" }, { "TIME", "TIME" }, }; var batchPrefix = $"{TestPrefix}StackExchange.Redis.Batch."; expected.AddRange(new TupleList <string, string> { { "DEBUG", $"DEBUG {batchPrefix}DebugObjectAsync" }, { "DDCUSTOM", $"DDCUSTOM" }, { "GEOADD", $"GEOADD {batchPrefix}GeoAddAsync" }, { "GEODIST", $"GEODIST {batchPrefix}GeoDistanceAsync" }, { "GEOHASH", $"GEOHASH {batchPrefix}GeoHashAsync" }, { "GEOPOS", $"GEOPOS {batchPrefix}GeoPositionAsync" }, { "GEORADIUSBYMEMBER", $"GEORADIUSBYMEMBER {batchPrefix}GeoRadiusAsync" }, { "ZREM", $"ZREM {batchPrefix}GeoRemoveAsync" }, { "HINCRBYFLOAT", $"HINCRBYFLOAT {batchPrefix}HashDecrementAsync" }, { "HDEL", $"HDEL {batchPrefix}HashDeleteAsync" }, { "HEXISTS", $"HEXISTS {batchPrefix}HashExistsAsync" }, { "HGETALL", $"HGETALL {batchPrefix}HashGetAllAsync" }, { "HINCRBYFLOAT", $"HINCRBYFLOAT {batchPrefix}HashIncrementAsync" }, { "HKEYS", $"HKEYS {batchPrefix}HashKeysAsync" }, { "HLEN", $"HLEN {batchPrefix}HashLengthAsync" }, { "HMSET", $"HMSET {batchPrefix}HashSetAsync" }, { "HVALS", $"HVALS {batchPrefix}HashValuesAsync" }, { "PFADD", $"PFADD {batchPrefix}HyperLogLogAddAsync" }, { "PFCOUNT", $"PFCOUNT {batchPrefix}HyperLogLogLengthAsync" }, { "PFMERGE", $"PFMERGE {batchPrefix}HyperLogLogMergeAsync" }, { "PING", $"PING" }, // { "DEL", $"DEL key" }, { "DUMP", $"DUMP key" }, { "EXISTS", $"EXISTS key" }, { "PEXPIREAT", $"PEXPIREAT key" }, { "MOVE", $"MOVE key" }, { "PERSIST", $"PERSIST key" }, { "RANDOMKEY", $"RANDOMKEY" }, { "RENAME", "RENAME key1" }, { "RESTORE", "RESTORE key" }, { "TYPE", "TYPE key" }, { "LINDEX", "LINDEX listkey" }, { "LINSERT", "LINSERT listkey" }, { "LINSERT", "LINSERT listkey" }, { "LPOP", "LPOP listkey" }, { "LPUSH", "LPUSH listkey" }, { "LLEN", "LLEN listkey" }, { "LRANGE", "LRANGE listkey" }, { "LREM", "LREM listkey" }, { "RPOP", "RPOP listkey" }, { "RPOPLPUSH", "RPOPLPUSH listkey" }, { "RPUSH", "RPUSH listkey" }, { "LSET", "LSET listkey" }, { "LTRIM", "LTRIM listkey" }, { "GET", "GET listkey" }, { "SET", "SET listkey" }, { "PUBLISH", "PUBLISH channel" }, { "SADD", "SADD setkey" }, { "SUNIONSTORE", "SUNIONSTORE setkey" }, { "SUNION", "SUNION setkey1" }, { "SISMEMBER", "SISMEMBER setkey" }, { "SCARD", "SCARD setkey" }, { "SMEMBERS", "SMEMBERS setkey" }, { "SMOVE", "SMOVE setkey1" }, { "SPOP", "SPOP setkey1" }, { "SRANDMEMBER", "SRANDMEMBER setkey" }, { "SRANDMEMBER", "SRANDMEMBER setkey" }, { "SREM", "SREM setkey" }, { "SORT", "SORT setkey" }, { "SORT", "SORT setkey" }, { "ZADD", "ZADD ssetkey" }, { "ZUNIONSTORE", "ZUNIONSTORE ssetkey1" }, { "ZINCRBY", "ZINCRBY ssetkey" }, { "ZINCRBY", "ZINCRBY ssetkey" }, { "ZCARD", "ZCARD ssetkey" }, { "ZLEXCOUNT", "ZLEXCOUNT ssetkey" }, { "ZRANGE", "ZRANGE ssetkey" }, { "ZRANGE", "ZRANGE ssetkey" }, { "ZRANGEBYSCORE", "ZRANGEBYSCORE ssetkey" }, { "ZRANGEBYSCORE", "ZRANGEBYSCORE ssetkey" }, { "ZRANGEBYLEX", "ZRANGEBYLEX ssetkey" }, { "ZRANK", "ZRANK ssetkey" }, { "ZREM", "ZREM ssetkey" }, { "ZREMRANGEBYRANK", "ZREMRANGEBYRANK ssetkey" }, { "ZREMRANGEBYSCORE", "ZREMRANGEBYSCORE ssetkey" }, { "ZREMRANGEBYLEX", "ZREMRANGEBYLEX ssetkey" }, { "ZSCORE", "ZSCORE ssestkey" }, { "APPEND", "APPEND ssetkey" }, { "BITCOUNT", "BITCOUNT ssetkey" }, { "BITOP", "BITOP" }, { "BITPOS", "BITPOS ssetkey1" }, { "INCRBYFLOAT", "INCRBYFLOAT key" }, { "GET", "GET key" }, { "GETBIT", "GETBIT key" }, { "GETRANGE", "GETRANGE key" }, { "GETSET", "GETSET key" }, { "INCR", "INCR key" }, { "STRLEN", "STRLEN key" }, { "SET", "SET key" }, { "SETBIT", "SETBIT key" }, { "SETRANGE", "SETRANGE key" }, }); var dbPrefix = $"{TestPrefix}StackExchange.Redis.Database."; expected.AddRange(new TupleList <string, string> { { "DEBUG", $"DEBUG {dbPrefix}DebugObject" }, { "DDCUSTOM", $"DDCUSTOM" }, { "GEOADD", $"GEOADD {dbPrefix}Geo" }, { "GEODIST", $"GEODIST {dbPrefix}Geo" }, { "GEOHASH", $"GEOHASH {dbPrefix}Geo" }, { "GEOPOS", $"GEOPOS {dbPrefix}Geo" }, { "GEORADIUSBYMEMBER", $"GEORADIUSBYMEMBER {dbPrefix}Geo" }, { "ZREM", $"ZREM {dbPrefix}Geo" }, { "HINCRBYFLOAT", $"HINCRBYFLOAT {dbPrefix}Hash" }, { "HDEL", $"HDEL {dbPrefix}Hash" }, { "HEXISTS", $"HEXISTS {dbPrefix}Hash" }, { "HGET", $"HGET {dbPrefix}Hash" }, { "HGETALL", $"HGETALL {dbPrefix}Hash" }, { "HINCRBY", $"HINCRBY {dbPrefix}Hash" }, { "HKEYS", $"HKEYS {dbPrefix}Hash" }, { "HLEN", $"HLEN {dbPrefix}Hash" }, // { "HSCAN", $"HSCAN {dbPrefix}Hash" }, { "HMSET", $"HMSET {dbPrefix}Hash" }, { "HVALS", $"HVALS {dbPrefix}Hash" }, { "PFADD", $"PFADD {dbPrefix}HyperLogLog" }, { "PFCOUNT", $"PFCOUNT {dbPrefix}HyperLogLog" }, { "PFMERGE", $"PFMERGE {dbPrefix}HyperLogLog2" }, // { "DEL", $"DEL {dbPrefix}Key" }, { "DUMP", $"DUMP {dbPrefix}Key" }, { "EXISTS", $"EXISTS {dbPrefix}Key" }, { "PEXPIREAT", $"PEXPIREAT {dbPrefix}Key" }, { "MIGRATE", $"MIGRATE {dbPrefix}Key" }, { "MOVE", $"MOVE {dbPrefix}Key" }, { "PERSIST", $"PERSIST {dbPrefix}Key" }, { "RANDOMKEY", $"RANDOMKEY" }, { "RENAME", $"RENAME {dbPrefix}Key" }, { "RESTORE", $"RESTORE {dbPrefix}Key" }, { "PTTL", $"PTTL {dbPrefix}Key" }, { "TYPE", $"TYPE {dbPrefix}Key" }, { "LINDEX", $"LINDEX {dbPrefix}List" }, { "LINSERT", $"LINSERT {dbPrefix}List" }, { "LINSERT", $"LINSERT {dbPrefix}List" }, { "LPOP", $"LPOP {dbPrefix}List" }, { "LPUSH", $"LPUSH {dbPrefix}List" }, { "LLEN", $"LLEN {dbPrefix}List" }, { "LRANGE", $"LRANGE {dbPrefix}List" }, { "LREM", $"LREM {dbPrefix}List" }, { "RPOP", $"RPOP {dbPrefix}List" }, { "RPOPLPUSH", $"RPOPLPUSH {dbPrefix}List" }, { "RPUSH", $"RPUSH {dbPrefix}List" }, { "LSET", $"LSET {dbPrefix}List" }, { "LTRIM", $"LTRIM {dbPrefix}List" }, { "GET", $"GET {dbPrefix}Lock" }, { "SET", $"SET {dbPrefix}Lock" }, { "PING", $"PING" }, { "PUBLISH", $"PUBLISH value" }, { "SADD", $"SADD {dbPrefix}Set" }, { "SUNION", $"SUNION {dbPrefix}Set" }, { "SUNIONSTORE", $"SUNIONSTORE {dbPrefix}Set" }, { "SISMEMBER", $"SISMEMBER {dbPrefix}Set" }, { "SCARD", $"SCARD {dbPrefix}Set" }, { "SMEMBERS", $"SMEMBERS {dbPrefix}Set" }, { "SMOVE", $"SMOVE {dbPrefix}Set" }, { "SPOP", $"SPOP {dbPrefix}Set" }, { "SRANDMEMBER", $"SRANDMEMBER {dbPrefix}Set" }, { "SRANDMEMBER", $"SRANDMEMBER {dbPrefix}Set" }, { "SREM", $"SREM {dbPrefix}Set" }, { "EXEC", $"EXEC" }, { "SORT", $"SORT {dbPrefix}Key" }, { "SORT", $"SORT {dbPrefix}Key" }, { "ZADD", $"ZADD {dbPrefix}SortedSet" }, { "ZUNIONSTORE", $"ZUNIONSTORE {dbPrefix}SortedSet2" }, { "ZINCRBY", $"ZINCRBY {dbPrefix}SortedSet" }, { "ZINCRBY", $"ZINCRBY {dbPrefix}SortedSet" }, { "ZCARD", $"ZCARD {dbPrefix}SortedSet" }, { "ZLEXCOUNT", $"ZLEXCOUNT {dbPrefix}SortedSet" }, { "ZRANGE", $"ZRANGE {dbPrefix}SortedSet" }, { "ZRANGE", $"ZRANGE {dbPrefix}SortedSet" }, { "ZRANGEBYSCORE", $"ZRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZRANGEBYSCORE", $"ZRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZRANGEBYLEX", $"ZRANGEBYLEX {dbPrefix}SortedSet" }, { "ZRANK", $"ZRANK {dbPrefix}SortedSet" }, { "ZREM", $"ZREM {dbPrefix}SortedSet" }, { "ZREMRANGEBYRANK", $"ZREMRANGEBYRANK {dbPrefix}SortedSet" }, { "ZREMRANGEBYSCORE", $"ZREMRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZREMRANGEBYLEX", $"ZREMRANGEBYLEX {dbPrefix}SortedSet" }, { "ZSCORE", $"ZSCORE {dbPrefix}SortedSet" }, { "APPEND", $"APPEND {dbPrefix}Key" }, { "BITCOUNT", $"BITCOUNT {dbPrefix}Key" }, { "BITOP", $"BITOP" }, { "BITPOS", $"BITPOS {dbPrefix}Key" }, { "INCRBYFLOAT", $"INCRBYFLOAT {dbPrefix}Key" }, { "GET", $"GET {dbPrefix}Key" }, { "GETBIT", $"GETBIT {dbPrefix}Key" }, { "GETRANGE", $"GETRANGE {dbPrefix}Key" }, { "GETSET", $"GETSET {dbPrefix}Key" }, { "PTTL+GET", $"PTTL+GET {dbPrefix}Key" }, { "STRLEN", $"STRLEN {dbPrefix}Key" }, { "SET", $"SET {dbPrefix}Key" }, { "SETBIT", $"SETBIT {dbPrefix}Key" }, { "SETRANGE", $"SETRANGE {dbPrefix}Key" }, }); var spans = agent.WaitForSpans(expected.Count).Where(s => s.Type == "redis").OrderBy(s => s.Start).ToList(); var host = Environment.GetEnvironmentVariable("REDIS_HOST") ?? "localhost"; foreach (var span in spans) { Assert.Equal("redis.command", span.Name); Assert.Equal("Samples.RedisCore-redis", span.Service); Assert.Equal(SpanTypes.Redis, span.Type); Assert.Equal(host, span.Tags.Get <string>("out.host")); Assert.Equal("6379", span.Tags.Get <string>("out.port")); } var spanLookup = new Dictionary <Tuple <string, string>, int>(); foreach (var span in spans) { var key = new Tuple <string, string>(span.Resource, span.Tags.Get <string>("redis.raw_command")); if (spanLookup.ContainsKey(key)) { spanLookup[key]++; } else { spanLookup[key] = 1; } } var missing = new List <Tuple <string, string> >(); foreach (var e in expected) { var found = spanLookup.ContainsKey(e); if (found) { if (--spanLookup[e] <= 0) { spanLookup.Remove(e); } } else { missing.Add(e); } } foreach (var e in missing) { Assert.True(false, $"no span found for `{e.Item1}`, `{e.Item2}`, remaining spans: `{string.Join(", ", spanLookup.Select(kvp => $"{kvp.Key.Item1}, {kvp.Key.Item2}").ToArray())}`"); } } }
public void SubmitsTraces(string packageVersion, string tagCommands) { int agentPort = TcpPortProvider.GetOpenPort(); var envVars = ZipkinEnvVars; envVars["SIGNALFX_INSTRUMENTATION_REDIS_TAG_COMMANDS"] = tagCommands; using (var agent = new MockZipkinCollector(agentPort)) using (var processResult = RunSampleAndWaitForExit(agent.Port, arguments: $"{TestPrefix}", packageVersion: packageVersion, envVars: envVars)) { Assert.True(processResult.ExitCode >= 0, $"Process exited with code {processResult.ExitCode}"); var expected = new TupleList <string, string> { { "SET", $"SET {TestPrefix}StackExchange.Redis.INCR" }, { "PING", "PING" }, { "INCR", $"INCR {TestPrefix}StackExchange.Redis.INCR" }, { "INCRBYFLOAT", $"INCRBYFLOAT {TestPrefix}StackExchange.Redis.INCR" }, { "GET", $"GET {TestPrefix}StackExchange.Redis.INCR" }, { "DDCUSTOM", "DDCUSTOM" }, { "ECHO", "ECHO" }, { "SLOWLOG", "SLOWLOG" }, { "TIME", "TIME" }, }; if (string.IsNullOrEmpty(packageVersion) || packageVersion.CompareTo("1.2.2") < 0) { expected.Remove(new Tuple <string, string>("DDCUSTOM", "DDCUSTOM")); expected.Remove(new Tuple <string, string>("ECHO", "ECHO")); expected.Remove(new Tuple <string, string>("SLOWLOG", "SLOWLOG")); expected.Remove(new Tuple <string, string>("TIME", "TIME")); } var batchPrefix = $"{TestPrefix}StackExchange.Redis.Batch."; expected.AddRange(new TupleList <string, string> { { "DEBUG", $"DEBUG {batchPrefix}DebugObjectAsync" }, { "DDCUSTOM", $"DDCUSTOM" }, // Only present on 1.2.2+ { "GEOADD", $"GEOADD {batchPrefix}GeoAddAsync" }, // Only present on 1.2.0+ { "GEODIST", $"GEODIST {batchPrefix}GeoDistanceAsync" }, // Only present on 1.2.0+ { "GEOHASH", $"GEOHASH {batchPrefix}GeoHashAsync" }, // Only present on 1.2.0+ { "GEOPOS", $"GEOPOS {batchPrefix}GeoPositionAsync" }, // Only present on 1.2.0+ { "GEORADIUSBYMEMBER", $"GEORADIUSBYMEMBER {batchPrefix}GeoRadiusAsync" }, // Only present on 1.2.0+ { "ZREM", $"ZREM {batchPrefix}GeoRemoveAsync" }, // Only present on 1.2.0+ { "HINCRBYFLOAT", $"HINCRBYFLOAT {batchPrefix}HashDecrementAsync" }, { "HDEL", $"HDEL {batchPrefix}HashDeleteAsync" }, { "HEXISTS", $"HEXISTS {batchPrefix}HashExistsAsync" }, { "HGETALL", $"HGETALL {batchPrefix}HashGetAllAsync" }, { "HINCRBYFLOAT", $"HINCRBYFLOAT {batchPrefix}HashIncrementAsync" }, { "HKEYS", $"HKEYS {batchPrefix}HashKeysAsync" }, { "HLEN", $"HLEN {batchPrefix}HashLengthAsync" }, { "HMSET", $"HMSET {batchPrefix}HashSetAsync" }, { "HVALS", $"HVALS {batchPrefix}HashValuesAsync" }, { "PFADD", $"PFADD {batchPrefix}HyperLogLogAddAsync" }, // Only present on 1.0.242+ { "PFCOUNT", $"PFCOUNT {batchPrefix}HyperLogLogLengthAsync" }, // Only present on 1.0.242+ { "PFMERGE", $"PFMERGE {batchPrefix}HyperLogLogMergeAsync" }, // Only present on 1.0.242+ { "PING", $"PING" }, // { "DEL", $"DEL key" }, { "DUMP", $"DUMP key" }, { "EXISTS", $"EXISTS key" }, { "PEXPIREAT", $"PEXPIREAT key" }, { "MOVE", $"MOVE key" }, { "PERSIST", $"PERSIST key" }, { "RANDOMKEY", $"RANDOMKEY" }, { "RENAME", "RENAME key1" }, { "RESTORE", "RESTORE key" }, { "TYPE", "TYPE key" }, { "LINDEX", "LINDEX listkey" }, { "LINSERT", "LINSERT listkey" }, { "LINSERT", "LINSERT listkey" }, { "LPOP", "LPOP listkey" }, { "LPUSH", "LPUSH listkey" }, { "LLEN", "LLEN listkey" }, { "LRANGE", "LRANGE listkey" }, { "LREM", "LREM listkey" }, { "RPOP", "RPOP listkey" }, { "RPOPLPUSH", "RPOPLPUSH listkey" }, { "RPUSH", "RPUSH listkey" }, { "LSET", "LSET listkey" }, { "LTRIM", "LTRIM listkey" }, { "GET", "GET listkey" }, { "SET", "SET listkey" }, { "PUBLISH", "PUBLISH channel" }, { "SADD", "SADD setkey" }, { "SUNIONSTORE", "SUNIONSTORE setkey" }, { "SUNION", "SUNION setkey1" }, { "SISMEMBER", "SISMEMBER setkey" }, { "SCARD", "SCARD setkey" }, { "SMEMBERS", "SMEMBERS setkey" }, { "SMOVE", "SMOVE setkey1" }, { "SPOP", "SPOP setkey1" }, { "SRANDMEMBER", "SRANDMEMBER setkey" }, { "SRANDMEMBER", "SRANDMEMBER setkey" }, { "SREM", "SREM setkey" }, { "SORT", "SORT setkey" }, // Only present on 1.0.206+ { "SORT", "SORT setkey" }, // Only present on 1.0.206+ { "ZUNIONSTORE", "ZUNIONSTORE ssetkey1" }, // Only present on 1.0.206+ { "ZADD", "ZADD ssetkey" }, { "ZINCRBY", "ZINCRBY ssetkey" }, { "ZINCRBY", "ZINCRBY ssetkey" }, { "ZCARD", "ZCARD ssetkey" }, { "ZRANGE", "ZRANGE ssetkey" }, { "ZRANGE", "ZRANGE ssetkey" }, { "ZRANGEBYSCORE", "ZRANGEBYSCORE ssetkey" }, { "ZRANGEBYSCORE", "ZRANGEBYSCORE ssetkey" }, { "ZRANK", "ZRANK ssetkey" }, { "ZREM", "ZREM ssetkey" }, { "ZREMRANGEBYRANK", "ZREMRANGEBYRANK ssetkey" }, { "ZREMRANGEBYSCORE", "ZREMRANGEBYSCORE ssetkey" }, { "ZSCORE", "ZSCORE ssestkey" }, { "ZLEXCOUNT", "ZLEXCOUNT ssetkey" }, // Only present on 1.0.273+ { "ZRANGEBYLEX", "ZRANGEBYLEX ssetkey" }, // Only present on 1.0.273+ { "ZREMRANGEBYLEX", "ZREMRANGEBYLEX ssetkey" }, // Only present on 1.0.273+ { "APPEND", "APPEND ssetkey" }, { "BITCOUNT", "BITCOUNT ssetkey" }, { "BITOP", "BITOP" }, { "BITPOS", "BITPOS ssetkey1" }, { "INCRBYFLOAT", "INCRBYFLOAT key" }, { "GET", "GET key" }, { "GETBIT", "GETBIT key" }, { "GETRANGE", "GETRANGE key" }, { "GETSET", "GETSET key" }, { "INCR", "INCR key" }, { "STRLEN", "STRLEN key" }, { "SET", "SET key" }, { "SETBIT", "SETBIT key" }, { "SETRANGE", "SETRANGE key" }, }); FilterExpectedResultsByApiVersion(expected, packageVersion); var dbPrefix = $"{TestPrefix}StackExchange.Redis.Database."; expected.AddRange(new TupleList <string, string> { { "DEBUG", $"DEBUG {dbPrefix}DebugObject" }, { "DDCUSTOM", $"DDCUSTOM" }, // Only present on 1.2.2+ { "GEOADD", $"GEOADD {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEODIST", $"GEODIST {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEOHASH", $"GEOHASH {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEOPOS", $"GEOPOS {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEORADIUSBYMEMBER", $"GEORADIUSBYMEMBER {dbPrefix}Geo" }, // Only present on 1.2.0+ { "ZREM", $"ZREM {dbPrefix}Geo" }, // Only present on 1.2.0+ { "HINCRBYFLOAT", $"HINCRBYFLOAT {dbPrefix}Hash" }, { "HDEL", $"HDEL {dbPrefix}Hash" }, { "HEXISTS", $"HEXISTS {dbPrefix}Hash" }, { "HGET", $"HGET {dbPrefix}Hash" }, { "HGETALL", $"HGETALL {dbPrefix}Hash" }, { "HINCRBY", $"HINCRBY {dbPrefix}Hash" }, { "HKEYS", $"HKEYS {dbPrefix}Hash" }, { "HLEN", $"HLEN {dbPrefix}Hash" }, // { "HSCAN", $"HSCAN {dbPrefix}Hash" }, { "HMSET", $"HMSET {dbPrefix}Hash" }, { "HVALS", $"HVALS {dbPrefix}Hash" }, { "PFADD", $"PFADD {dbPrefix}HyperLogLog" }, // Only present on 1.0.242+ { "PFCOUNT", $"PFCOUNT {dbPrefix}HyperLogLog" }, // Only present on 1.0.242+ { "PFMERGE", $"PFMERGE {dbPrefix}HyperLogLog2" }, // Only present on 1.0.242+ // { "DEL", $"DEL {dbPrefix}Key" }, { "DUMP", $"DUMP {dbPrefix}Key" }, { "EXISTS", $"EXISTS {dbPrefix}Key" }, { "PEXPIREAT", $"PEXPIREAT {dbPrefix}Key" }, { "MIGRATE", $"MIGRATE {dbPrefix}Key" }, // Only present on 1.0.297+ { "MOVE", $"MOVE {dbPrefix}Key" }, { "PERSIST", $"PERSIST {dbPrefix}Key" }, { "RANDOMKEY", $"RANDOMKEY" }, { "RENAME", $"RENAME {dbPrefix}Key" }, { "RESTORE", $"RESTORE {dbPrefix}Key" }, { "PTTL", $"PTTL {dbPrefix}Key" }, { "TYPE", $"TYPE {dbPrefix}Key" }, { "LINDEX", $"LINDEX {dbPrefix}List" }, { "LINSERT", $"LINSERT {dbPrefix}List" }, { "LINSERT", $"LINSERT {dbPrefix}List" }, { "LPOP", $"LPOP {dbPrefix}List" }, { "LPUSH", $"LPUSH {dbPrefix}List" }, { "LLEN", $"LLEN {dbPrefix}List" }, { "LRANGE", $"LRANGE {dbPrefix}List" }, { "LREM", $"LREM {dbPrefix}List" }, { "RPOP", $"RPOP {dbPrefix}List" }, { "RPOPLPUSH", $"RPOPLPUSH {dbPrefix}List" }, { "RPUSH", $"RPUSH {dbPrefix}List" }, { "LSET", $"LSET {dbPrefix}List" }, { "LTRIM", $"LTRIM {dbPrefix}List" }, { "GET", $"GET {dbPrefix}Lock" }, { "SET", $"SET {dbPrefix}Lock" }, { "PING", $"PING" }, { "PUBLISH", $"PUBLISH value" }, { "SADD", $"SADD {dbPrefix}Set" }, { "SUNION", $"SUNION {dbPrefix}Set" }, { "SUNIONSTORE", $"SUNIONSTORE {dbPrefix}Set" }, { "SISMEMBER", $"SISMEMBER {dbPrefix}Set" }, { "SCARD", $"SCARD {dbPrefix}Set" }, { "SMEMBERS", $"SMEMBERS {dbPrefix}Set" }, { "SMOVE", $"SMOVE {dbPrefix}Set" }, { "SPOP", $"SPOP {dbPrefix}Set" }, { "SRANDMEMBER", $"SRANDMEMBER {dbPrefix}Set" }, { "SRANDMEMBER", $"SRANDMEMBER {dbPrefix}Set" }, { "SREM", $"SREM {dbPrefix}Set" }, { "EXEC", $"EXEC" }, { "SORT", $"SORT {dbPrefix}Key" }, // Only present on 1.0.206+ { "SORT", $"SORT {dbPrefix}Key" }, // Only present on 1.0.206+ { "ZUNIONSTORE", $"ZUNIONSTORE {dbPrefix}SortedSet2" }, // Only present on 1.0.206+ { "ZADD", $"ZADD {dbPrefix}SortedSet" }, { "ZINCRBY", $"ZINCRBY {dbPrefix}SortedSet" }, { "ZINCRBY", $"ZINCRBY {dbPrefix}SortedSet" }, { "ZCARD", $"ZCARD {dbPrefix}SortedSet" }, { "ZRANGE", $"ZRANGE {dbPrefix}SortedSet" }, { "ZRANGE", $"ZRANGE {dbPrefix}SortedSet" }, { "ZRANGEBYSCORE", $"ZRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZRANGEBYSCORE", $"ZRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZRANK", $"ZRANK {dbPrefix}SortedSet" }, { "ZREM", $"ZREM {dbPrefix}SortedSet" }, { "ZREMRANGEBYRANK", $"ZREMRANGEBYRANK {dbPrefix}SortedSet" }, { "ZREMRANGEBYSCORE", $"ZREMRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZSCORE", $"ZSCORE {dbPrefix}SortedSet" }, { "ZLEXCOUNT", $"ZLEXCOUNT {dbPrefix}SortedSet" }, // Only present on 1.0.273+ { "ZRANGEBYLEX", $"ZRANGEBYLEX {dbPrefix}SortedSet" }, // Only present on 1.0.273+ { "ZREMRANGEBYLEX", $"ZREMRANGEBYLEX {dbPrefix}SortedSet" }, // Only present on 1.0.273+ { "APPEND", $"APPEND {dbPrefix}Key" }, { "BITCOUNT", $"BITCOUNT {dbPrefix}Key" }, { "BITOP", $"BITOP" }, { "BITPOS", $"BITPOS {dbPrefix}Key" }, { "INCRBYFLOAT", $"INCRBYFLOAT {dbPrefix}Key" }, { "GET", $"GET {dbPrefix}Key" }, { "GETBIT", $"GETBIT {dbPrefix}Key" }, { "GETRANGE", $"GETRANGE {dbPrefix}Key" }, { "GETSET", $"GETSET {dbPrefix}Key" }, { "PTTL+GET", $"PTTL+GET {dbPrefix}Key" }, { "STRLEN", $"STRLEN {dbPrefix}Key" }, { "SET", $"SET {dbPrefix}Key" }, { "SETBIT", $"SETBIT {dbPrefix}Key" }, { "SETRANGE", $"SETRANGE {dbPrefix}Key" }, }); FilterExpectedResultsByApiVersion(expected, packageVersion); // No db.statement tags should exists, so overwrite with null if (!tagCommands.Equals("true")) { var replacement = new TupleList <string, string>(); foreach (var item in expected) { replacement.Add(new Tuple <string, string>(item.Item1, null)); } expected = replacement; } var spans = agent.WaitForSpans(expected.Count).Where(s => s.Tags.GetValueOrDefault <string>("db.type") == "redis").OrderBy(s => s.Start).ToList(); var host = Environment.GetEnvironmentVariable("STACKEXCHANGE_REDIS_HOST") ?? "localhost:6389"; var port = host.Substring(host.IndexOf(':') + 1); host = host.Substring(0, host.IndexOf(':')); foreach (var span in spans) { Assert.Equal("Samples.StackExchange.Redis", span.Service); Assert.Equal("StackExchange.Redis", span.Tags.GetValueOrDefault <string>("component")); Assert.Equal(SpanKinds.Client, span.Tags.GetValueOrDefault <string>("span.kind")); Assert.Equal(host, span.Tags.GetValueOrDefault <string>("peer.hostname")); Assert.Equal(port, span.Tags.GetValueOrDefault <string>("peer.port")); } var spanLookup = new Dictionary <Tuple <string, string>, int>(); foreach (var span in spans) { var key = new Tuple <string, string>(span.Name, span.Tags.GetValueOrDefault <string>("db.statement")); if (spanLookup.ContainsKey(key)) { spanLookup[key]++; } else { spanLookup[key] = 1; } } var missing = new List <Tuple <string, string> >(); foreach (var e in expected) { var found = spanLookup.ContainsKey(e); if (found) { if (--spanLookup[e] <= 0) { spanLookup.Remove(e); } } else { missing.Add(e); } } foreach (var e in missing) { Assert.True(false, $"no span found for `{e.Item1}`, `{e.Item2}`, remaining spans: `{string.Join(", ", spanLookup.Select(kvp => $"{kvp.Key.Item1}, {kvp.Key.Item2}").ToArray())}`"); } } }
public static async Task <Tuple <IOrganizationServiceExtented, TupleList <SelectedFile, WebResource> > > GetWebResourcesWithType(IWriteToOutput _iWriteToOutput, List <SelectedFile> selectedFiles, OpenFilesType openFilesType, ConnectionData connectionData) { IOrganizationServiceExtented service = null; TupleList <SelectedFile, WebResource> filesToOpen = new TupleList <SelectedFile, WebResource>(); if (openFilesType == OpenFilesType.All) { foreach (var item in selectedFiles) { filesToOpen.Add(item, null); } } else if (openFilesType == OpenFilesType.NotExistsInCrmWithoutLink || openFilesType == OpenFilesType.NotExistsInCrmWithLink ) { var compareResult = await FindFilesNotExistsInCrmAsync(_iWriteToOutput, selectedFiles, connectionData); service = compareResult.Item1; if (openFilesType == OpenFilesType.NotExistsInCrmWithoutLink) { filesToOpen.AddRange(compareResult.Item2.Select(f => Tuple.Create(f, (WebResource)null))); } else if (openFilesType == OpenFilesType.NotExistsInCrmWithLink) { filesToOpen.AddRange(compareResult.Item3.Select(f => Tuple.Create(f.Item1, f.Item2))); } } else if (openFilesType == OpenFilesType.EqualByText || openFilesType == OpenFilesType.NotEqualByText ) { var compareResult = await ComparingFilesAndWebResourcesAsync(_iWriteToOutput, selectedFiles, connectionData, false); service = compareResult.Item1; if (openFilesType == OpenFilesType.EqualByText) { filesToOpen.AddRange(compareResult.Item2); } else if (openFilesType == OpenFilesType.NotEqualByText) { filesToOpen.AddRange(compareResult.Item3.Select(f => Tuple.Create(f.Item1, f.Item2))); } } else if (openFilesType == OpenFilesType.WithInserts || openFilesType == OpenFilesType.WithDeletes || openFilesType == OpenFilesType.WithComplex || openFilesType == OpenFilesType.WithMirror || openFilesType == OpenFilesType.WithMirrorInserts || openFilesType == OpenFilesType.WithMirrorDeletes || openFilesType == OpenFilesType.WithMirrorComplex ) { var compareResult = await CompareController.ComparingFilesAndWebResourcesAsync(_iWriteToOutput, selectedFiles, connectionData, true); service = compareResult.Item1; if (openFilesType == OpenFilesType.WithInserts) { filesToOpen.AddRange(compareResult.Item3.Where(s => s.Item3.IsOnlyInserts).Select(f => Tuple.Create(f.Item1, f.Item2))); } else if (openFilesType == OpenFilesType.WithDeletes) { filesToOpen.AddRange(compareResult.Item3.Where(s => s.Item3.IsOnlyDeletes).Select(f => Tuple.Create(f.Item1, f.Item2))); } else if (openFilesType == OpenFilesType.WithComplex) { filesToOpen.AddRange(compareResult.Item3.Where(s => s.Item3.IsComplexChanges).Select(f => Tuple.Create(f.Item1, f.Item2))); } else if (openFilesType == OpenFilesType.WithMirror) { filesToOpen.AddRange(compareResult.Item3.Where(s => s.Item3.IsMirror).Select(f => Tuple.Create(f.Item1, f.Item2))); } else if (openFilesType == OpenFilesType.WithMirrorInserts) { filesToOpen.AddRange(compareResult.Item3.Where(s => s.Item3.IsMirrorWithInserts).Select(f => Tuple.Create(f.Item1, f.Item2))); } else if (openFilesType == OpenFilesType.WithMirrorDeletes) { filesToOpen.AddRange(compareResult.Item3.Where(s => s.Item3.IsMirrorWithDeletes).Select(f => Tuple.Create(f.Item1, f.Item2))); } else if (openFilesType == OpenFilesType.WithMirrorComplex) { filesToOpen.AddRange(compareResult.Item3.Where(s => s.Item3.IsMirrorWithComplex).Select(f => Tuple.Create(f.Item1, f.Item2))); } } return(Tuple.Create(service, filesToOpen)); }
public void SubmitsTraces(string packageVersion) { using var telemetry = this.ConfigureTelemetry(); using (var agent = EnvironmentHelper.GetMockAgent()) using (RunSampleAndWaitForExit(agent, arguments: $"{TestPrefix}", packageVersion: packageVersion)) { var expected = new TupleList <string, string> { { "SET", $"SET {TestPrefix}StackExchange.Redis.INCR" }, { "PING", "PING" }, { "INCR", $"INCR {TestPrefix}StackExchange.Redis.INCR" }, { "INCRBYFLOAT", $"INCRBYFLOAT {TestPrefix}StackExchange.Redis.INCR" }, { "GET", $"GET {TestPrefix}StackExchange.Redis.INCR" }, { "DDCUSTOM", "DDCUSTOM" }, { "ECHO", "ECHO" }, { "SLOWLOG", "SLOWLOG" }, { "TIME", "TIME" }, }; if (string.IsNullOrEmpty(packageVersion) || packageVersion.CompareTo("1.2.2") < 0) { expected.Remove(new Tuple <string, string>("DDCUSTOM", "DDCUSTOM")); expected.Remove(new Tuple <string, string>("ECHO", "ECHO")); expected.Remove(new Tuple <string, string>("SLOWLOG", "SLOWLOG")); expected.Remove(new Tuple <string, string>("TIME", "TIME")); } var batchPrefix = $"{TestPrefix}StackExchange.Redis.Batch."; expected.AddRange(new TupleList <string, string> { { "DEBUG", $"DEBUG {batchPrefix}DebugObjectAsync" }, { "DDCUSTOM", $"DDCUSTOM" }, // Only present on 1.2.2+ { "GEOADD", $"GEOADD {batchPrefix}GeoAddAsync" }, // Only present on 1.2.0+ { "GEODIST", $"GEODIST {batchPrefix}GeoDistanceAsync" }, // Only present on 1.2.0+ { "GEOHASH", $"GEOHASH {batchPrefix}GeoHashAsync" }, // Only present on 1.2.0+ { "GEOPOS", $"GEOPOS {batchPrefix}GeoPositionAsync" }, // Only present on 1.2.0+ { "GEORADIUSBYMEMBER", $"GEORADIUSBYMEMBER {batchPrefix}GeoRadiusAsync" }, // Only present on 1.2.0+ { "ZREM", $"ZREM {batchPrefix}GeoRemoveAsync" }, // Only present on 1.2.0+ { "HINCRBYFLOAT", $"HINCRBYFLOAT {batchPrefix}HashDecrementAsync" }, { "HDEL", $"HDEL {batchPrefix}HashDeleteAsync" }, { "HEXISTS", $"HEXISTS {batchPrefix}HashExistsAsync" }, { "HGETALL", $"HGETALL {batchPrefix}HashGetAllAsync" }, { "HINCRBYFLOAT", $"HINCRBYFLOAT {batchPrefix}HashIncrementAsync" }, { "HKEYS", $"HKEYS {batchPrefix}HashKeysAsync" }, { "HLEN", $"HLEN {batchPrefix}HashLengthAsync" }, { "HMSET", $"HMSET {batchPrefix}HashSetAsync" }, { "HVALS", $"HVALS {batchPrefix}HashValuesAsync" }, { "PFADD", $"PFADD {batchPrefix}HyperLogLogAddAsync" }, // Only present on 1.0.242+ { "PFCOUNT", $"PFCOUNT {batchPrefix}HyperLogLogLengthAsync" }, // Only present on 1.0.242+ { "PFMERGE", $"PFMERGE {batchPrefix}HyperLogLogMergeAsync" }, // Only present on 1.0.242+ { "PING", $"PING" }, // { "DEL", $"DEL key" }, { "DUMP", $"DUMP key" }, { "EXISTS", $"EXISTS key" }, { "PEXPIRE", $"PEXPIRE key" }, { "MOVE", $"MOVE key" }, { "PERSIST", $"PERSIST key" }, { "RANDOMKEY", $"RANDOMKEY" }, { "RENAME", "RENAME key1" }, { "RESTORE", "RESTORE key" }, { "TYPE", "TYPE key" }, { "LINDEX", "LINDEX listkey" }, { "LINSERT", "LINSERT listkey" }, { "LINSERT", "LINSERT listkey" }, { "LPOP", "LPOP listkey" }, { "LPUSH", "LPUSH listkey" }, { "LLEN", "LLEN listkey" }, { "LRANGE", "LRANGE listkey" }, { "LREM", "LREM listkey" }, { "RPOP", "RPOP listkey" }, { "RPOPLPUSH", "RPOPLPUSH listkey" }, { "RPUSH", "RPUSH listkey" }, { "LSET", "LSET listkey" }, { "LTRIM", "LTRIM listkey" }, { "GET", "GET listkey" }, { "SET", "SET listkey" }, { "PUBLISH", "PUBLISH channel" }, { "SADD", "SADD setkey" }, { "SUNIONSTORE", "SUNIONSTORE setkey" }, { "SUNION", "SUNION setkey1" }, { "SISMEMBER", "SISMEMBER setkey" }, { "SCARD", "SCARD setkey" }, { "SMEMBERS", "SMEMBERS setkey" }, { "SMOVE", "SMOVE setkey1" }, { "SPOP", "SPOP setkey1" }, { "SRANDMEMBER", "SRANDMEMBER setkey" }, { "SRANDMEMBER", "SRANDMEMBER setkey" }, { "SREM", "SREM setkey" }, { "SORT", "SORT setkey" }, // Only present on 1.0.206+ { "SORT", "SORT setkey" }, // Only present on 1.0.206+ { "ZUNIONSTORE", "ZUNIONSTORE ssetkey1" }, // Only present on 1.0.206+ { "ZADD", "ZADD ssetkey" }, { "ZINCRBY", "ZINCRBY ssetkey" }, { "ZINCRBY", "ZINCRBY ssetkey" }, { "ZCARD", "ZCARD ssetkey" }, { "ZRANGE", "ZRANGE ssetkey" }, { "ZRANGE", "ZRANGE ssetkey" }, { "ZRANGEBYSCORE", "ZRANGEBYSCORE ssetkey" }, { "ZRANGEBYSCORE", "ZRANGEBYSCORE ssetkey" }, { "ZRANK", "ZRANK ssetkey" }, { "ZREM", "ZREM ssetkey" }, { "ZREMRANGEBYRANK", "ZREMRANGEBYRANK ssetkey" }, { "ZREMRANGEBYSCORE", "ZREMRANGEBYSCORE ssetkey" }, { "ZSCORE", "ZSCORE ssestkey" }, { "ZLEXCOUNT", "ZLEXCOUNT ssetkey" }, // Only present on 1.0.273+ { "ZRANGEBYLEX", "ZRANGEBYLEX ssetkey" }, // Only present on 1.0.273+ { "ZREMRANGEBYLEX", "ZREMRANGEBYLEX ssetkey" }, // Only present on 1.0.273+ { "APPEND", "APPEND ssetkey" }, { "BITCOUNT", "BITCOUNT ssetkey" }, { "BITOP", "BITOP" }, { "BITPOS", "BITPOS ssetkey1" }, { "INCRBYFLOAT", "INCRBYFLOAT key" }, { "GET", "GET key" }, { "GETBIT", "GETBIT key" }, { "GETRANGE", "GETRANGE key" }, { "GETSET", "GETSET key" }, { "INCR", "INCR key" }, { "STRLEN", "STRLEN key" }, { "SET", "SET key" }, { "SETBIT", "SETBIT key" }, { "SETRANGE", "SETRANGE key" }, }); FilterExpectedResultsByApiVersion(expected, packageVersion); var dbPrefix = $"{TestPrefix}StackExchange.Redis.Database."; expected.AddRange(new TupleList <string, string> { { "DEBUG", $"DEBUG {dbPrefix}DebugObject" }, { "DDCUSTOM", $"DDCUSTOM" }, // Only present on 1.2.2+ { "GEOADD", $"GEOADD {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEODIST", $"GEODIST {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEOHASH", $"GEOHASH {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEOPOS", $"GEOPOS {dbPrefix}Geo" }, // Only present on 1.2.0+ { "GEORADIUSBYMEMBER", $"GEORADIUSBYMEMBER {dbPrefix}Geo" }, // Only present on 1.2.0+ { "ZREM", $"ZREM {dbPrefix}Geo" }, // Only present on 1.2.0+ { "HINCRBYFLOAT", $"HINCRBYFLOAT {dbPrefix}Hash" }, { "HDEL", $"HDEL {dbPrefix}Hash" }, { "HEXISTS", $"HEXISTS {dbPrefix}Hash" }, { "HGET", $"HGET {dbPrefix}Hash" }, { "HGETALL", $"HGETALL {dbPrefix}Hash" }, { "HINCRBY", $"HINCRBY {dbPrefix}Hash" }, { "HKEYS", $"HKEYS {dbPrefix}Hash" }, { "HLEN", $"HLEN {dbPrefix}Hash" }, // { "HSCAN", $"HSCAN {dbPrefix}Hash" }, { "HMSET", $"HMSET {dbPrefix}Hash" }, { "HVALS", $"HVALS {dbPrefix}Hash" }, { "PFADD", $"PFADD {dbPrefix}HyperLogLog" }, // Only present on 1.0.242+ { "PFCOUNT", $"PFCOUNT {dbPrefix}HyperLogLog" }, // Only present on 1.0.242+ { "PFMERGE", $"PFMERGE {dbPrefix}HyperLogLog2" }, // Only present on 1.0.242+ // { "DEL", $"DEL {dbPrefix}Key" }, { "DUMP", $"DUMP {dbPrefix}Key" }, { "EXISTS", $"EXISTS {dbPrefix}Key" }, { "PEXPIRE", $"PEXPIRE {dbPrefix}Key" }, { "MIGRATE", $"MIGRATE {dbPrefix}Key" }, // Only present on 1.0.297+ { "MOVE", $"MOVE {dbPrefix}Key" }, { "PERSIST", $"PERSIST {dbPrefix}Key" }, { "RANDOMKEY", $"RANDOMKEY" }, { "RENAME", $"RENAME {dbPrefix}Key" }, { "RESTORE", $"RESTORE {dbPrefix}Key" }, { "PTTL", $"PTTL {dbPrefix}Key" }, { "TYPE", $"TYPE {dbPrefix}Key" }, { "LINDEX", $"LINDEX {dbPrefix}List" }, { "LINSERT", $"LINSERT {dbPrefix}List" }, { "LINSERT", $"LINSERT {dbPrefix}List" }, { "LPOP", $"LPOP {dbPrefix}List" }, { "LPUSH", $"LPUSH {dbPrefix}List" }, { "LLEN", $"LLEN {dbPrefix}List" }, { "LRANGE", $"LRANGE {dbPrefix}List" }, { "LREM", $"LREM {dbPrefix}List" }, { "RPOP", $"RPOP {dbPrefix}List" }, { "RPOPLPUSH", $"RPOPLPUSH {dbPrefix}List" }, { "RPUSH", $"RPUSH {dbPrefix}List" }, { "LSET", $"LSET {dbPrefix}List" }, { "LTRIM", $"LTRIM {dbPrefix}List" }, { "GET", $"GET {dbPrefix}Lock" }, { "SET", $"SET {dbPrefix}Lock" }, { "PING", $"PING" }, { "PUBLISH", $"PUBLISH value" }, { "SADD", $"SADD {dbPrefix}Set" }, { "SUNION", $"SUNION {dbPrefix}Set" }, { "SUNIONSTORE", $"SUNIONSTORE {dbPrefix}Set" }, { "SISMEMBER", $"SISMEMBER {dbPrefix}Set" }, { "SCARD", $"SCARD {dbPrefix}Set" }, { "SMEMBERS", $"SMEMBERS {dbPrefix}Set" }, { "SMOVE", $"SMOVE {dbPrefix}Set" }, { "SPOP", $"SPOP {dbPrefix}Set" }, { "SRANDMEMBER", $"SRANDMEMBER {dbPrefix}Set" }, { "SRANDMEMBER", $"SRANDMEMBER {dbPrefix}Set" }, { "SREM", $"SREM {dbPrefix}Set" }, { "EXEC", $"EXEC" }, { "SORT", $"SORT {dbPrefix}Key" }, // Only present on 1.0.206+ { "SORT", $"SORT {dbPrefix}Key" }, // Only present on 1.0.206+ { "ZUNIONSTORE", $"ZUNIONSTORE {dbPrefix}SortedSet2" }, // Only present on 1.0.206+ { "ZADD", $"ZADD {dbPrefix}SortedSet" }, { "ZINCRBY", $"ZINCRBY {dbPrefix}SortedSet" }, { "ZINCRBY", $"ZINCRBY {dbPrefix}SortedSet" }, { "ZCARD", $"ZCARD {dbPrefix}SortedSet" }, { "ZRANGE", $"ZRANGE {dbPrefix}SortedSet" }, { "ZRANGE", $"ZRANGE {dbPrefix}SortedSet" }, { "ZRANGEBYSCORE", $"ZRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZRANGEBYSCORE", $"ZRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZRANK", $"ZRANK {dbPrefix}SortedSet" }, { "ZREM", $"ZREM {dbPrefix}SortedSet" }, { "ZREMRANGEBYRANK", $"ZREMRANGEBYRANK {dbPrefix}SortedSet" }, { "ZREMRANGEBYSCORE", $"ZREMRANGEBYSCORE {dbPrefix}SortedSet" }, { "ZSCORE", $"ZSCORE {dbPrefix}SortedSet" }, { "ZLEXCOUNT", $"ZLEXCOUNT {dbPrefix}SortedSet" }, // Only present on 1.0.273+ { "ZRANGEBYLEX", $"ZRANGEBYLEX {dbPrefix}SortedSet" }, // Only present on 1.0.273+ { "ZREMRANGEBYLEX", $"ZREMRANGEBYLEX {dbPrefix}SortedSet" }, // Only present on 1.0.273+ { "APPEND", $"APPEND {dbPrefix}Key" }, { "BITCOUNT", $"BITCOUNT {dbPrefix}Key" }, { "BITOP", $"BITOP" }, { "BITPOS", $"BITPOS {dbPrefix}Key" }, { "INCRBYFLOAT", $"INCRBYFLOAT {dbPrefix}Key" }, { "GET", $"GET {dbPrefix}Key" }, { "GETBIT", $"GETBIT {dbPrefix}Key" }, { "GETRANGE", $"GETRANGE {dbPrefix}Key" }, { "GETSET", $"GETSET {dbPrefix}Key" }, { "PTTL+GET", $"PTTL+GET {dbPrefix}Key" }, { "STRLEN", $"STRLEN {dbPrefix}Key" }, { "SET", $"SET {dbPrefix}Key" }, { "SETBIT", $"SETBIT {dbPrefix}Key" }, { "SETRANGE", $"SETRANGE {dbPrefix}Key" }, }); FilterExpectedResultsByApiVersion(expected, packageVersion); var spans = agent.WaitForSpans(expected.Count).Where(s => s.Type == "redis").OrderBy(s => s.Start).ToList(); var host = Environment.GetEnvironmentVariable("STACKEXCHANGE_REDIS_HOST") ?? "localhost:6389"; var port = host.Substring(host.IndexOf(':') + 1); host = host.Substring(0, host.IndexOf(':')); foreach (var span in spans) { Assert.Equal("redis.command", span.Name); Assert.Equal("Samples.StackExchange.Redis-redis", span.Service); Assert.Equal(SpanTypes.Redis, span.Type); Assert.Equal(host, DictionaryExtensions.GetValueOrDefault(span.Tags, "out.host")); Assert.Equal(port, DictionaryExtensions.GetValueOrDefault(span.Tags, "out.port")); Assert.False(span.Tags?.ContainsKey(Tags.Version), "External service span should not have service version tag."); } var spanLookup = new Dictionary <Tuple <string, string>, int>(); foreach (var span in spans) { var key = new Tuple <string, string>(span.Resource, DictionaryExtensions.GetValueOrDefault(span.Tags, "redis.raw_command")); if (spanLookup.ContainsKey(key)) { spanLookup[key]++; } else { spanLookup[key] = 1; } } var missing = new List <Tuple <string, string> >(); foreach (var e in expected) { var found = spanLookup.ContainsKey(e); if (found) { if (--spanLookup[e] <= 0) { spanLookup.Remove(e); } } else { missing.Add(e); } } foreach (var e in missing) { Assert.True(false, $"no span found for `{e.Item1}`, `{e.Item2}`, remaining spans: `{string.Join(", ", spanLookup.Select(kvp => $"{kvp.Key.Item1}, {kvp.Key.Item2}").ToArray())}`"); } telemetry.AssertIntegrationEnabled(IntegrationId.StackExchangeRedis); } }