Skip to content

Commit 7fd90f6

Browse files
author
claudiamurialdo
committed
Add detailed trace logging for cache operations and tenant identification
1 parent b74c19d commit 7fd90f6

3 files changed

Lines changed: 114 additions & 45 deletions

File tree

dotnet/src/dotnetcore/GxNetCoreStartup/SessionHelper.cs

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
using Microsoft.AspNetCore.Http;
2-
using Microsoft.Extensions.Caching.Distributed;
3-
using Microsoft.Extensions.Caching.StackExchangeRedis;
1+
using System;
42
using System.Collections.Concurrent;
5-
using System.Threading.Tasks;
3+
using System.Linq;
64
using System.Threading;
7-
using System;
5+
using System.Threading.Tasks;
86
using GeneXus.Services;
9-
using System.Linq;
7+
using Microsoft.AspNetCore.Http;
8+
using Microsoft.Extensions.Caching.Distributed;
9+
using Microsoft.Extensions.Caching.StackExchangeRedis;
1010

1111
namespace GeneXus.Application
1212
{
1313
public class TenantRedisCache : IDistributedCache
1414
{
15+
private static readonly IGXLogger log = GXLoggerFactory.GetLogger<TenantRedisCache>();
16+
1517
private readonly IHttpContextAccessor _httpContextAccessor;
1618
private readonly IServiceProvider _serviceProvider;
1719
private readonly ConcurrentDictionary<string, RedisCache> _redisCaches = new();
@@ -25,32 +27,85 @@ public TenantRedisCache(IHttpContextAccessor httpContextAccessor, IServiceProvid
2527
private IDistributedCache GetTenantCache()
2628
{
2729
string tenantId = _httpContextAccessor.HttpContext?.Items[TenantMiddleware.TENANT_ID]?.ToString() ?? "default";
28-
29-
return _redisCaches.GetOrAdd(tenantId, id =>
30+
RedisCache cache;
31+
bool existed = _redisCaches.TryGetValue(tenantId, out cache);
32+
if (existed)
33+
{
34+
log.LogDebug($"GetTenantCache: tenantId={tenantId}, cache reused");
35+
return cache;
36+
}
37+
else
3038
{
31-
ISessionService sessionService = GXSessionServiceFactory.GetProvider();
32-
var options = new RedisCacheOptions
39+
log.LogDebug($"GetTenantCache: tenantId={tenantId}, cache created");
40+
cache = _redisCaches.GetOrAdd(tenantId, id =>
3341
{
34-
Configuration = sessionService.ConnectionString,
35-
InstanceName = $"{id}:"
36-
};
37-
return new RedisCache(options);
38-
});
42+
ISessionService sessionService = GXSessionServiceFactory.GetProvider();
43+
var options = new RedisCacheOptions
44+
{
45+
Configuration = sessionService.ConnectionString,
46+
InstanceName = $"{id}:"
47+
};
48+
return new RedisCache(options);
49+
});
50+
}
51+
return cache;
52+
}
53+
public byte[] Get(string key)
54+
{
55+
IDistributedCache cache = GetTenantCache();
56+
log.LogDebug($"CacheGet: key={key}");
57+
return cache.Get(key);
58+
}
59+
public Task<byte[]> GetAsync(string key, CancellationToken token = default)
60+
{
61+
IDistributedCache cache = GetTenantCache();
62+
log.LogDebug($"CacheGetAsync: key={key}");
63+
return cache.GetAsync(key, token);
64+
}
65+
public void Refresh(string key)
66+
{
67+
IDistributedCache cache = GetTenantCache();
68+
log.LogDebug($"CacheRefresh: key={key}");
69+
cache.Refresh(key);
70+
}
71+
public Task RefreshAsync(string key, CancellationToken token = default)
72+
{
73+
IDistributedCache cache = GetTenantCache();
74+
log.LogDebug($"CacheRefreshAsync: key={key}");
75+
return cache.RefreshAsync(key, token);
76+
}
77+
public void Remove(string key)
78+
{
79+
IDistributedCache cache = GetTenantCache();
80+
log.LogDebug($"CacheRemove: key={key}");
81+
cache.Remove(key);
82+
}
83+
public Task RemoveAsync(string key, CancellationToken token = default)
84+
{
85+
IDistributedCache cache = GetTenantCache();
86+
log.LogDebug($"CacheRemoveAsync: key={key}");
87+
return cache.RemoveAsync(key, token);
88+
}
89+
public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
90+
{
91+
string sliding = options?.SlidingExpiration?.ToString() ?? "none";
92+
IDistributedCache cache = GetTenantCache();
93+
log.LogDebug($"CacheSet: key={key}, slidingExpiration={sliding}");
94+
cache.Set(key, value, options);
95+
}
96+
public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default)
97+
{
98+
string sliding = options?.SlidingExpiration?.ToString() ?? "none";
99+
IDistributedCache cache = GetTenantCache();
100+
log.LogDebug($"CacheSetAsync: key={key}, slidingExpiration={sliding}");
101+
return cache.SetAsync(key, value, options, token);
39102
}
40-
41-
public byte[] Get(string key) => GetTenantCache().Get(key);
42-
public Task<byte[]> GetAsync(string key, CancellationToken token = default) => GetTenantCache().GetAsync(key, token);
43-
public void Refresh(string key) => GetTenantCache().Refresh(key);
44-
public Task RefreshAsync(string key, CancellationToken token = default) => GetTenantCache().RefreshAsync(key, token);
45-
public void Remove(string key) => GetTenantCache().Remove(key);
46-
public Task RemoveAsync(string key, CancellationToken token = default) => GetTenantCache().RemoveAsync(key, token);
47-
public void Set(string key, byte[] value, DistributedCacheEntryOptions options) => GetTenantCache().Set(key, value, options);
48-
public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default) => GetTenantCache().SetAsync(key, value, options, token);
49103
}
50104

51-
52105
public class TenantMiddleware
53106
{
107+
private static readonly IGXLogger log = GXLoggerFactory.GetLogger<TenantMiddleware>();
108+
54109
internal const string TENANT_ID = "TenantId";
55110
private readonly RequestDelegate _next;
56111

@@ -63,8 +118,9 @@ public async Task Invoke(HttpContext context)
63118
{
64119
string host = context.Request.Host.Host;
65120
string subdomain = host.Split('.').FirstOrDefault();
66-
context.Items[TENANT_ID] = subdomain;
121+
context.Items[TENANT_ID] = subdomain;
67122

123+
log.LogDebug($"TenantMiddleware: host={host}, subdomain={subdomain}, path={context.Request.Path}");
68124
await _next(context);
69125
}
70126
}

dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
using Microsoft.AspNetCore.Hosting;
2020
using Microsoft.AspNetCore.Http;
2121
using Microsoft.AspNetCore.Http.Features;
22-
using Microsoft.AspNetCore.HttpOverrides;
2322
using Microsoft.AspNetCore.Mvc;
2423
using Microsoft.AspNetCore.Rewrite;
2524
using Microsoft.AspNetCore.Routing;

dotnet/src/dotnetframework/GxClasses/Domain/GxSession.cs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public string Id
7676
{
7777
if (_httpSession != null)
7878
{
79-
GXLogging.Debug(log, "SessionId : " + _httpSession.SessionID);
79+
GXLogging.Debug(log, "SId : " + _httpSession.SessionID);
8080
return _httpSession.SessionID;
8181
}
8282
return string.Empty;
@@ -86,62 +86,76 @@ public string Id
8686
public void Set(string key, string val)
8787
{
8888
key = GXUtil.NormalizeKey(key);
89-
GXLogging.DebugSanitized(log, "Set Key" + key + "=" + val);
9089
if (_httpSession != null)
9190
{
92-
GXLogging.Debug(log, "SetObject SessionId : " + _httpSession.SessionID);
91+
GXLogging.Debug(log, $"Set: SId={_httpSession.SessionID}, Key={key}, Value={val}");
9392
_httpSession[key] = val;
9493
}
94+
else
95+
{
96+
GXLogging.Debug(log, $"Set: Key={key}, Value={val}, No active session");
97+
}
9598
}
9699
public string Get(string key)
97100
{
98101
key = GXUtil.NormalizeKey(key);
99102
if (_httpSession != null)
100103
{
101-
GXLogging.Debug(log, "GetObject SessionId : " + _httpSession.SessionID);
102-
if (_httpSession[key] == null)
104+
object value = _httpSession[key];
105+
if (value == null)
103106
{
104-
GXLogging.Debug(log, "Get key: " + key + " is Empty");
107+
GXLogging.Debug(log, $"Get: SId={_httpSession.SessionID}, Key={key}, Value=<empty>");
105108
return string.Empty;
106109
}
107110
else
108111
{
109-
object value = _httpSession[key];
110-
GXLogging.Debug(log, "Get key: " + key + "=" + value.ToString());
112+
GXLogging.Debug(log, $"Get: SId={_httpSession.SessionID}, Key={key}, Value={value}");
111113
return value.ToString();
112114
}
113115
}
116+
GXLogging.Debug(log, $"Get: Key={key}, No active session");
114117
return string.Empty;
115118
}
116119
public T Get<T>(string key) where T: class
117120
{
118121
key = GXUtil.NormalizeKey(key);
119122
if (_httpSession != null)
120123
{
121-
GXLogging.Debug(log, "GetObject SessionId : " + _httpSession.SessionID);
122-
if (_httpSession[key] == null)
124+
object value = _httpSession[key];
125+
if (value == null)
126+
{
127+
GXLogging.Debug(log, $"Get: SId={_httpSession.SessionID}, Key={key}, Value=<empty>");
123128
return null;
129+
}
130+
else
131+
{
132+
GXLogging.Debug(log, $"Get: SId={_httpSession.SessionID}, Key={key}, Value={value}");
124133
#if NETCORE
125-
return JSONHelper.DeserializeNullDefaultValue<T>(_httpSession[key]);
134+
return JSONHelper.DeserializeNullDefaultValue<T>(_httpSession[key]);
126135
#else
127-
return (T)_httpSession[key];
136+
return (T)_httpSession[key];
128137
#endif
138+
}
129139
}
140+
GXLogging.Debug(log, $"Get: Key={key}, No active session");
130141
return null;
131142
}
132143
public void Set<T>(string key, T val) where T : class
133144
{
134145
key = GXUtil.NormalizeKey(key);
135-
GXLogging.Debug(log, "Set Key" + key + "=" + val);
136146
if (_httpSession != null)
137147
{
138-
GXLogging.Debug(log, "SetObject SessionId : " + _httpSession.SessionID);
148+
GXLogging.Debug(log, $"Set: SId={_httpSession.SessionID}, Key={key}, Value={val}");
139149
#if NETCORE
140150
_httpSession[key] = JSONHelper.Serialize<T>(val);
141151
#else
142152
_httpSession[key] = val;
143153
#endif
144154
}
155+
else
156+
{
157+
GXLogging.Debug(log, $"Set: Key={key}, Value={val}, No active session");
158+
}
145159
}
146160

147161
public void Remove(string key)
@@ -150,15 +164,15 @@ public void Remove(string key)
150164
GXLogging.Debug(log, "Remove key: " + key );
151165
if (_httpSession != null)
152166
{
153-
GXLogging.Debug(log, "Remove SessionId : " + _httpSession.SessionID);
167+
GXLogging.Debug(log, "Remove SId : " + _httpSession.SessionID);
154168
_httpSession.Remove(key);
155169
}
156170
}
157171
public void Destroy()
158172
{
159173
if (_httpSession != null)
160174
{
161-
GXLogging.Debug(log, "Destroy sessionId: " + _httpSession.SessionID);
175+
GXLogging.Debug(log, "Destroy SId: " + _httpSession.SessionID);
162176
_httpSession.RemoveAll();
163177
_httpSession.Abandon();
164178
#if !NETCORE
@@ -174,7 +188,7 @@ public void Renew()
174188
{
175189
if (_httpSession != null)
176190
{
177-
GXLogging.Debug(log, "Renew sessionId: " + _httpSession.SessionID);
191+
GXLogging.Debug(log, "Renew SId: " + _httpSession.SessionID);
178192
BackupInternalKeys();
179193
_httpSession.RemoveAll();
180194
RestoreInternalKeys();
@@ -209,7 +223,7 @@ public void Clear()
209223
{
210224
if (_httpSession != null)
211225
{
212-
GXLogging.Debug(log, "Clear sessionId: " + _httpSession.SessionID);
226+
GXLogging.Debug(log, "Clear SId: " + _httpSession.SessionID);
213227
BackupInternalKeys();
214228
_httpSession.Clear();
215229
RestoreInternalKeys();

0 commit comments

Comments
 (0)