Example #1
0
        public DatabasesInfoRetriever(ServerStore serverStore, CanAccessDatabase canAccessDatabase)
        {
            _serverStore       = serverStore;
            _canAccessDatabase = canAccessDatabase;

            Initialize();
        }
Example #2
0
        public override DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
        {
            var items = new DynamicJsonArray();

            foreach (var mountPointUsage in Items)
            {
                var usageAsJson = mountPointUsage.ToJsonWithFilter(filter);
                if (usageAsJson != null)
                {
                    usageAsJson.RemoveInMemoryPropertyByName(nameof(MountPointUsage.Items));

                    items.Add(usageAsJson);
                }
            }

            if (items.Count == 0)
            {
                return(null);
            }

            var json = base.ToJson();

            json[nameof(Items)] = items;

            return(json);
        }
Example #3
0
        public DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
        {
            var json = ToJsonInternal();

            var ravenSize            = 0L;
            var ravenTempBuffersSize = 0L;

            var items = new DynamicJsonArray();

            foreach (var databaseDiskUsage in Items)
            {
                if (filter(databaseDiskUsage.Database, requiresWrite: false))
                {
                    items.Add(databaseDiskUsage.ToJson());
                    ravenSize            += databaseDiskUsage.Size;
                    ravenTempBuffersSize += databaseDiskUsage.TempBuffersSize;
                }
            }

            if (items.Count == 0)
            {
                return(null);
            }

            json[nameof(Items)]                = items;
            json[nameof(RavenSize)]            = ravenSize;
            json[nameof(RavenTempBuffersSize)] = ravenTempBuffersSize;

            return(json);
        }
 public ClusterDashboardConnection(WebSocket webSocket, CanAccessDatabase canAccessDatabase, ClusterDashboardNotifications clusterDashboardNotifications,
                                   IMemoryContextPool contextPool, CancellationToken resourceShutdown)
     : base(webSocket, clusterDashboardNotifications, contextPool, resourceShutdown)
 {
     _canAccessDatabase             = canAccessDatabase;
     _clusterDashboardNotifications = clusterDashboardNotifications;
     _returnReadContext             = contextPool.AllocateOperationContext(out _readContext);
 }
Example #5
0
 private async Task SendNotifications(CanAccessDatabase canAccessDatabase, WebSocket webSocket)
 {
     using (var notifications = new ClusterDashboardNotifications(Server, canAccessDatabase, ServerStore.ServerShutdown))
         using (var connection = new ClusterDashboardConnection(webSocket, canAccessDatabase, notifications,
                                                                ServerStore.ContextPool, ServerStore.ServerShutdown))
         {
             await connection.Handle();
         }
 }
Example #6
0
        public override DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
        {
            var result = new TrafficWatchPayload();

            foreach (TrafficWatchItem item in TrafficPerDatabase)
            {
                if (filter(item.Database, requiresWrite: false))
                {
                    result.Add(item);
                }
            }

            return result.ToJsonInternal();
        }
Example #7
0
        public override DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
        {
            var result = new IndexingSpeedPayload();

            foreach (IndexingSpeedItem item in IndexingSpeedPerDatabase)
            {
                if (filter(item.Database, requiresWrite: false))
                {
                    result.Add(item);
                }
            }

            return(result.ToJsonInternal());
        }
Example #8
0
        public override DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
        {
            var items = new DynamicJsonArray();

            foreach (var indexingSpeedItem in Items)
            {
                if (filter(indexingSpeedItem.Database, requiresWrite: false))
                {
                    items.Add(indexingSpeedItem.ToJson());
                }
            }

            if (items.Count == 0)
            {
                return(null);
            }

            var json = base.ToJson();

            json[nameof(Items)] = items;
            return(json);
        }
Example #9
0
        public async Task WriteNotifications(CanAccessDatabase shouldWriteByDb, Task taskHandlingReceiveOfData = null)
        {
            var receiveBuffer = new ArraySegment <byte>(new byte[1024]);
            var receive       = taskHandlingReceiveOfData ?? _webSocket.ReceiveAsync(receiveBuffer, _resourceShutdown);

            var asyncQueue = new AsyncQueue <DynamicJsonValue>();

            try
            {
                using (_notificationsBase.TrackActions(asyncQueue, this, shouldWriteByDb))
                {
                    AfterTrackActionsRegistration?.Invoke();

                    while (_resourceShutdown.IsCancellationRequested == false)
                    {
                        // we use this to detect client-initialized closure
                        if (receive.IsCompleted)
                        {
                            break;
                        }

                        var tuple = await asyncQueue.TryDequeueAsync(TimeSpan.FromSeconds(5));

                        if (tuple.Item1 == false)
                        {
                            await SendHeartbeat();

                            continue;
                        }

                        await WriteToWebSocket(tuple.Item2);
                    }
                }
            }
            catch (OperationCanceledException)
            {
            }
        }
Example #10
0
        public override DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
        {
            var items = new DynamicJsonArray();

            foreach (var trafficWatchItem in Items)
            {
                if (filter(trafficWatchItem.Database, requiresWrite: false))
                {
                    items.Add(trafficWatchItem.ToJson());
                }
            }

            if (items.Count == 0)
            {
                return(null);
            }

            var json = base.ToJson();

            json[nameof(Items)] = items;
            json[nameof(AverageRequestDuration)] = AverageRequestDuration;
            return(json);
        }
Example #11
0
        public IDisposable TrackActions(AsyncQueue <DynamicJsonValue> notificationsQueue, IWebsocketWriter webSocketWriter, CanAccessDatabase shouldWriteByDb = null)
        {
            var watcher = new ConnectedWatcher
            {
                NotificationsQueue = notificationsQueue,
                Writer             = webSocketWriter,
                Filter             = shouldWriteByDb
            };

            lock (_watchersLock)
            {
                Watchers.TryAdd(watcher);

                if (Watchers.Count == 1)
                {
                    StartBackgroundWorkers();
                }

                if (watcher.Writer is NotificationCenterWebSocketWriter)
                {
                    if (_state.NumberOfClients == 0)
                    {
                        var copy = _state;
                        // we use interlocked here to make sure that other threads
                        // are immediately exposed to this
                        Interlocked.Exchange(ref _state, new State
                        {
                            NumberOfClients = 1
                        });
                        copy.NewWebSocket.TrySetResult(null);
                    }
                    else
                    {
                        Interlocked.Increment(ref _state.NumberOfClients);
                    }
                }
            }

            return(new DisposableAction(() =>
            {
                lock (_watchersLock)
                {
                    Watchers.TryRemove(watcher);

                    if (Watchers.Count == 0)
                    {
                        StopBackgroundWorkers();
                    }

                    if (watcher.Writer is NotificationCenterWebSocketWriter)
                    {
                        var copy = _state;
                        if (Interlocked.Decrement(ref copy.NumberOfClients) == 0)
                        {
                            Interlocked.Exchange(ref _state, new State());
                            copy.AllWebSocketsRemoved.TrySetResult(null);
                        }
                    }
                }
            }));
        }
Example #12
0
 public override DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
 {
     return(ToJson());
 }
 public ClusterDashboardNotifications(RavenServer server, CanAccessDatabase canAccessDatabase, CancellationToken shutdown)
 {
     _server   = server;
     _shutdown = shutdown;
     _databasesInfoRetriever = new DatabasesInfoRetriever(server.ServerStore, canAccessDatabase);
 }
Example #14
0
        public static IEnumerable <AbstractDashboardNotification> FetchDatabasesInfo(ServerStore serverStore, CanAccessDatabase isValidFor, CancellationToken token)
        {
            var databasesInfo             = new DatabasesInfo();
            var databasesOngoingTasksInfo = new DatabasesOngoingTasksInfo();
            var indexingSpeed             = new IndexingSpeed();
            var trafficWatch = new TrafficWatch();
            var drivesUsage  = new DrivesUsage();

            trafficWatch.AverageRequestDuration = serverStore.Server.Metrics.Requests.AverageDuration.GetRate();

            using (serverStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context))
                using (context.OpenReadTransaction())
                {
                    // 1. Fetch databases info
                    foreach (var databaseTuple in serverStore.Cluster.ItemsStartingWith(context, Constants.Documents.Prefix, 0, long.MaxValue))
                    {
                        var databaseName = databaseTuple.ItemName.Substring(Constants.Documents.Prefix.Length);
                        if (token.IsCancellationRequested)
                        {
                            yield break;
                        }

                        if (isValidFor != null && isValidFor(databaseName, false) == false)
                        {
                            continue;
                        }

                        if (serverStore.DatabasesLandlord.DatabasesCache.TryGetValue(databaseName, out var databaseTask) == false)
                        {
                            // database does not exist on this server, is offline or disabled
                            SetOfflineDatabaseInfo(serverStore, context, databaseName, databasesInfo, drivesUsage, disabled: DatabasesLandlord.IsDatabaseDisabled(databaseTuple.Value));
                            continue;
                        }

                        try
                        {
                            var databaseOnline = IsDatabaseOnline(databaseTask, out var database);
                            if (databaseOnline == false)
                            {
                                SetOfflineDatabaseInfo(serverStore, context, databaseName, databasesInfo, drivesUsage, disabled: false);
                                continue;
                            }

                            var rate = (int)RefreshRate.TotalSeconds;

                            var indexingSpeedItem = new IndexingSpeedItem
                            {
                                Database         = database.Name,
                                IndexedPerSecond = database.Metrics.MapIndexes.IndexedPerSec.GetRate(rate),
                                MappedPerSecond  = database.Metrics.MapReduceIndexes.MappedPerSec.GetRate(rate),
                                ReducedPerSecond = database.Metrics.MapReduceIndexes.ReducedPerSec.GetRate(rate)
                            };
                            indexingSpeed.Items.Add(indexingSpeedItem);

                            var replicationFactor = GetReplicationFactor(databaseTuple.Value);
                            var documentsStorage  = database.DocumentsStorage;
                            var indexStorage      = database.IndexStore;

                            var trafficWatchItem = new TrafficWatchItem
                            {
                                Database                       = database.Name,
                                RequestsPerSecond              = (int)database.Metrics.Requests.RequestsPerSec.GetRate(rate),
                                AverageRequestDuration         = database.Metrics.Requests.AverageDuration.GetRate(),
                                DocumentWritesPerSecond        = (int)database.Metrics.Docs.PutsPerSec.GetRate(rate),
                                AttachmentWritesPerSecond      = (int)database.Metrics.Attachments.PutsPerSec.GetRate(rate),
                                CounterWritesPerSecond         = (int)database.Metrics.Counters.PutsPerSec.GetRate(rate),
                                TimeSeriesWritesPerSecond      = (int)database.Metrics.TimeSeries.PutsPerSec.GetRate(rate),
                                DocumentsWriteBytesPerSecond   = database.Metrics.Docs.BytesPutsPerSec.GetRate(rate),
                                AttachmentsWriteBytesPerSecond = database.Metrics.Attachments.BytesPutsPerSec.GetRate(rate),
                                CountersWriteBytesPerSecond    = database.Metrics.Counters.BytesPutsPerSec.GetRate(rate),
                                TimeSeriesWriteBytesPerSecond  = database.Metrics.TimeSeries.BytesPutsPerSec.GetRate(rate)
                            };
                            trafficWatch.Items.Add(trafficWatchItem);

                            databasesOngoingTasksInfo.Items.Add(GetOngoingTasksInfoItem(database, serverStore, context, out var ongoingTasksCount));

                            // TODO: RavenDB-17004 - hash should report on all relevant info
                            var currentEnvironmentsHash = database.GetEnvironmentsHash();

                            if (CachedDatabaseInfo.TryGetValue(database.Name, out var item) &&
                                item.Hash == currentEnvironmentsHash &&
                                item.Item.OngoingTasksCount == ongoingTasksCount)
                            {
                                databasesInfo.Items.Add(item.Item);

                                if (item.NextDiskSpaceCheck < SystemTime.UtcNow)
                                {
                                    item.MountPoints = new List <Client.ServerWide.Operations.MountPointUsage>();
                                    DiskUsageCheck(item, database, drivesUsage, token);
                                }
                                else
                                {
                                    foreach (var cachedMountPoint in item.MountPoints)
                                    {
                                        UpdateMountPoint(database.Configuration.Storage, cachedMountPoint, database.Name, drivesUsage);
                                    }
                                }
                            }
                            else
                            {
                                using (documentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext documentsContext))
                                    using (documentsContext.OpenReadTransaction())
                                    {
                                        var databaseInfoItem = new DatabaseInfoItem
                                        {
                                            Database              = database.Name,
                                            DocumentsCount        = documentsStorage.GetNumberOfDocuments(documentsContext),
                                            IndexesCount          = database.IndexStore.Count,
                                            AlertsCount           = database.NotificationCenter.GetAlertCount(),
                                            PerformanceHintsCount = database.NotificationCenter.GetPerformanceHintCount(),
                                            ReplicationFactor     = replicationFactor,
                                            ErroredIndexesCount   = indexStorage.GetIndexes().Count(index => index.State == IndexState.Error),
                                            IndexingErrorsCount   = indexStorage.GetIndexes().Sum(index => index.GetErrorCount()),
                                            BackupInfo            = database.PeriodicBackupRunner?.GetBackupInfo(context),
                                            OngoingTasksCount     = ongoingTasksCount,
                                            Online = true
                                        };

                                        databasesInfo.Items.Add(databaseInfoItem);

                                        CachedDatabaseInfo[database.Name] = item = new DatabaseInfoCache
                                        {
                                            Hash = currentEnvironmentsHash,
                                            Item = databaseInfoItem
                                        };
                                    }

                                DiskUsageCheck(item, database, drivesUsage, token);
                            }
                        }
                        catch (Exception)
                        {
                            SetOfflineDatabaseInfo(serverStore, context, databaseName, databasesInfo, drivesUsage, disabled: false);
                        }
                    }

                    // 2. Fetch <system> info
                    if (isValidFor == null)
                    {
                        var currentSystemHash    = serverStore._env.CurrentReadTransactionId;
                        var cachedSystemInfoCopy = CachedSystemInfo;

                        if (currentSystemHash != cachedSystemInfoCopy.Hash || cachedSystemInfoCopy.NextDiskSpaceCheck < SystemTime.UtcNow)
                        {
                            var systemInfo = new SystemInfoCache()
                            {
                                Hash = currentSystemHash,
                                NextDiskSpaceCheck = SystemTime.UtcNow.AddSeconds(30),
                                MountPoints        = new List <Client.ServerWide.Operations.MountPointUsage>()
                            };

                            // Get new data
                            var systemEnv         = new StorageEnvironmentWithType("<System>", StorageEnvironmentWithType.StorageEnvironmentType.System, serverStore._env);
                            var systemMountPoints = ServerStore.GetMountPointUsageDetailsFor(systemEnv, includeTempBuffers: true);

                            foreach (var systemPoint in systemMountPoints)
                            {
                                UpdateMountPoint(serverStore.Configuration.Storage, systemPoint, "<System>", drivesUsage);
                                systemInfo.MountPoints.Add(systemPoint);
                            }

                            // Update the cache
                            Interlocked.Exchange(ref CachedSystemInfo, systemInfo);
                        }
                        else
                        {
                            // Use existing data
                            foreach (var systemPoint in cachedSystemInfoCopy.MountPoints)
                            {
                                UpdateMountPoint(serverStore.Configuration.Storage, systemPoint, "<System>", drivesUsage);
                            }
                        }
                    }
                }

            yield return(databasesInfo);

            yield return(databasesOngoingTasksInfo);

            yield return(indexingSpeed);

            yield return(trafficWatch);

            yield return(drivesUsage);
        }
 /// <summary>
 /// Convert object to DynamicJsonValue but using provided filter
 /// Return null when filter matches nothing - such message will be skipped
 /// </summary>
 public abstract DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter);