Repository navigation
Expand file tree
/
Copy pathRedisModule.cs
More file actions
146 lines (125 loc) · 5.49 KB
/
Copy pathRedisModule.cs
File metadata and controls
146 lines (125 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Microsoft.Extensions.Configuration;
using Opserver.Helpers;
using static Opserver.Data.Redis.RedisInfo;
namespace Opserver.Data.Redis
{
public class RedisModule : StatusModule<RedisSettings>
{
public override string Name => "Redis";
public override bool Enabled => Instances.Count > 0;
public List<RedisReplicationGroup> ReplicationGroups { get; }
public List<RedisHost> Hosts { get; }
public List<RedisInstance> Instances { get; }
public List<RedisConnectionInfo> Connections { get; }
private readonly HashSet<string> HostNames;
public RedisModule(IConfiguration config, PollingService poller, AddressCache addressCache) : base(config, poller)
{
Connections = LoadRedisConnections(Settings, addressCache);
Instances = Connections.Select(rci => new RedisInstance(this, rci))
.Where(rsi => rsi.TryAddToGlobalPollers())
.ToList();
Hosts = Instances.GroupBy(i => i.ConnectionInfo.Server)
.Select(g => { g.Key.Instances = g.ToList(); return g.Key; })
.ToList();
ReplicationGroups = Hosts.Where(h => h.ReplicationGroupName.HasValue())
.GroupBy(h => h.ReplicationGroupName)
.Select(g => new RedisReplicationGroup(g.Key, g.ToList()))
.ToList();
HostNames = new HashSet<string>(Hosts.Select(h => h.HostName), StringComparer.OrdinalIgnoreCase);
}
public override MonitorStatus MonitorStatus => Instances.GetWorstStatus();
public override bool IsMember(string node) => HostNames.Contains(node);
private List<RedisConnectionInfo> LoadRedisConnections(RedisSettings settings, AddressCache addressCache)
{
var result = new List<RedisConnectionInfo>();
var defaultServerInstances = settings.Defaults.Instances;
var allServerInstances = settings.AllServers.Instances ?? Enumerable.Empty<RedisSettings.Instance>();
foreach (var s in settings.Servers)
{
var server = new RedisHost(this, s);
var count = result.Count;
// Add instances that belong to any servers
foreach (var asi in allServerInstances)
{
result.Add(new RedisConnectionInfo(server, asi, addressCache));
}
// Add instances defined on this server
foreach (var si in s.Instances)
{
result.Add(new RedisConnectionInfo(server, si, addressCache));
}
// If we have no instances added at this point, defaults it is!
if (defaultServerInstances != null && count == result.Count)
{
foreach (var dsi in defaultServerInstances)
{
result.Add(new RedisConnectionInfo(server, dsi, addressCache));
}
}
}
return result;
}
public RedisHost GetHost(string hostName)
{
if (hostName.IsNullOrEmpty() || hostName.Contains(":")) return null;
return Hosts.Find(h => string.Equals(h.HostName, hostName, StringComparison.InvariantCultureIgnoreCase));
}
public RedisInstance GetInstance(RedisConnectionInfo info)
{
foreach (var i in Instances)
{
if (i.ConnectionInfo == info) return i;
}
return null;
}
public RedisInstance GetInstance(string connectionString)
{
if (connectionString.IsNullOrEmpty()) return null;
if (connectionString.Contains(":"))
{
var parts = connectionString.Split(StringSplits.Colon);
if (parts.Length != 2) return null;
if (int.TryParse(parts[1], out int port)) return GetInstance(parts[0], port);
}
else
{
return GetAllInstances(connectionString).FirstOrDefault();
}
return null;
}
public RedisInstance GetInstance(string host, int port)
{
foreach (var ri in Instances)
{
if (ri.Host.HostName == host && ri.Port == port) return ri;
}
var shortHost = host.Split(StringSplits.Period)[0];
foreach (var ri in Instances)
{
if (ri.Port == port && ri.ShortHost == shortHost) return ri;
}
return null;
}
public RedisInstance GetInstance(int port, IPAddress ipAddress)
{
foreach (var i in Instances)
{
if (i.ConnectionInfo.Port != port) continue;
foreach (var ip in i.ConnectionInfo.IPAddresses)
{
if (ip.Equals(ipAddress)) return i;
}
}
return null;
}
public RedisInstance GetInstance(RedisReplicaInfo info) => GetInstance(info.Port, info.IPAddress);
public List<RedisInstance> GetAllInstances(string node)
{
return Instances.Where(ri => string.Equals(ri.Host.HostName, node, StringComparison.InvariantCultureIgnoreCase)).ToList();
}
}
}