Ejemplo n.º 1
0
        private ArraySegment <byte> ToByteArraySegment(TrafficWatchChange change)
        {
            var json = new DynamicJsonValue
            {
                [nameof(change.TimeStamp)]           = change.TimeStamp,
                [nameof(change.RequestId)]           = change.RequestId,
                [nameof(change.HttpMethod)]          = change.HttpMethod,
                [nameof(change.ElapsedMilliseconds)] = change.ElapsedMilliseconds,
                [nameof(change.ResponseStatusCode)]  = change.ResponseStatusCode,
                [nameof(change.RequestUri)]          = change.RequestUri,
                [nameof(change.AbsoluteUri)]         = change.AbsoluteUri,
                [nameof(change.DatabaseName)]        = change.DatabaseName,
                [nameof(change.CustomInfo)]          = change.CustomInfo,
                [nameof(change.InnerRequestsCount)]  = change.InnerRequestsCount
                                                       //[nameof(change.QueryTimings)] = notification.QueryTimings
            };

            _bufferStream.SetLength(0);
            using (_jsonContextPool.AllocateOperationContext(out JsonOperationContext context))
                using (var writer = new BlittableJsonTextWriter(context, _bufferStream))
                {
                    context.Write(writer, json);
                    writer.Flush();

                    _bufferStream.TryGetBuffer(out ArraySegment <byte> bytes);
                    return(bytes);
                }
        }
Ejemplo n.º 2
0
        private ArraySegment <byte> ToByteArraySegment(TrafficWatchChange change)
        {
            var json = new DynamicJsonValue
            {
                [nameof(change.TimeStamp)]           = change.TimeStamp,
                [nameof(change.RequestId)]           = change.RequestId,
                [nameof(change.HttpMethod)]          = change.HttpMethod,
                [nameof(change.ElapsedMilliseconds)] = change.ElapsedMilliseconds,
                [nameof(change.ResponseStatusCode)]  = change.ResponseStatusCode,
                [nameof(change.RequestUri)]          = change.RequestUri,
                [nameof(change.AbsoluteUri)]         = change.AbsoluteUri,
                [nameof(change.DatabaseName)]        = change.DatabaseName,
                [nameof(change.CustomInfo)]          = change.CustomInfo,
                [nameof(change.Type)]     = change.Type,
                [nameof(change.ClientIP)] = change.ClientIP
            };

            _bufferStream.SetLength(0);
            using (var writer = new BlittableJsonTextWriter(_context, _bufferStream))
            {
                _context.Write(writer, json);
                writer.Flush();

                _bufferStream.TryGetBuffer(out var bytes);
                return(bytes);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// LogTrafficWatch gets HttpContext, elapsed time and database name
        /// </summary>
        /// <param name="context"></param>
        /// <param name="elapsedMilliseconds"></param>
        /// <param name="database"></param>
        private void LogTrafficWatch(HttpContext context, long elapsedMilliseconds, string database)
        {
            var requestId   = Interlocked.Increment(ref _requestId);
            var contextItem = context.Items["TrafficWatch"];

            (string CustomInfo, TrafficWatchChangeType Type)twTuple =
                ((string, TrafficWatchChangeType)?)contextItem ?? ("N/A", TrafficWatchChangeType.None);

            var twn = new TrafficWatchChange
            {
                TimeStamp           = DateTime.UtcNow,
                RequestId           = requestId,                       // counted only for traffic watch
                HttpMethod          = context.Request.Method ?? "N/A", // N/A ?
                ElapsedMilliseconds = elapsedMilliseconds,
                ResponseStatusCode  = context.Response.StatusCode,
                RequestUri          = context.Request.GetEncodedUrl(),
                AbsoluteUri         = $"{context.Request.Scheme}://{context.Request.Host}",
                DatabaseName        = database ?? "N/A",
                CustomInfo          = twTuple.CustomInfo,
                Type = twTuple.Type,
                InnerRequestsCount = 0,
                QueryTimings       = null
            };

            TrafficWatchManager.DispatchMessage(twn);
        }
Ejemplo n.º 4
0
        private ArraySegment <byte> ToByteArraySegment(TrafficWatchChange change)
        {
            var json = new DynamicJsonValue
            {
                ["TimeStamp"]           = change.TimeStamp,
                ["RequestId"]           = change.RequestId,
                ["HttpMethod"]          = change.HttpMethod,
                ["ElapsedMilliseconds"] = change.ElapsedMilliseconds,
                ["ResponseStatusCode"]  = change.ResponseStatusCode,
                ["RequestUri"]          = change.RequestUri,
                ["AbsoluteUri"]         = change.AbsoluteUri,
                ["TenantName"]          = change.TenantName,
                ["CustomInfo"]          = change.CustomInfo,
                ["InnerRequestsCount"]  = change.InnerRequestsCount
                                          //["QueryTimings"] = notification.QueryTimings // TODO :: implement this
            };

            _bufferStream.SetLength(0);
            using (_jsonContextPool.AllocateOperationContext(out JsonOperationContext context))
                using (var writer = new BlittableJsonTextWriter(context, _bufferStream))
                {
                    context.Write(writer, json);
                    writer.Flush();

                    _bufferStream.TryGetBuffer(out ArraySegment <byte> bytes);
                    return(bytes);
                }
        }
Ejemplo n.º 5
0
        public static void DispatchMessage(TrafficWatchChange trafficWatchData)
        {
            foreach (var connection in ServerHttpTrace)
            {
                if (connection.IsAlive == false)
                {
                    Disconnect(connection);
                    continue;
                }

                if (connection.TenantSpecific != null)
                {
                    if (string.Equals(connection.TenantSpecific, trafficWatchData.DatabaseName, StringComparison.OrdinalIgnoreCase) == false)
                    {
                        continue;
                    }
                }
                connection.EnqueMsg(trafficWatchData);
            }
        }
Ejemplo n.º 6
0
        private void LogTrafficWatch(HttpContext context, long elapsedMilliseconds, string database)
        {
            var requestId = Interlocked.Increment(ref _requestId);

            var twn = new TrafficWatchChange
            {
                TimeStamp           = DateTime.UtcNow,
                RequestId           = requestId,                       // counted only for traffic watch
                HttpMethod          = context.Request.Method ?? "N/A", // N/A ?
                ElapsedMilliseconds = elapsedMilliseconds,
                ResponseStatusCode  = context.Response.StatusCode,
                RequestUri          = context.Request.GetEncodedUrl(),
                AbsoluteUri         = $@"{context.Request.Scheme}://{context.Request.Host}",
                DatabaseName        = database ?? "N/A",
                CustomInfo          = "",  // TODO: Implement
                InnerRequestsCount  = 0,   // TODO: Implement
                QueryTimings        = null // TODO: Implement
            };

            TrafficWatchManager.DispatchMessage(twn);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Connects to raven traffic event source and registers all the requests to the file defined in the config
        /// </summary>
        /// <param name="config">configuration conatining the connection, the file to write to, etc.</param>
        /// <param name="store">the store to work with</param>
        private async Task RecordRequests(TrafficToolConfiguration config, IDocumentStore store)
        {
            var id = Guid.NewGuid().ToString();

            using (var client = new ClientWebSocket())
            {
                var url = store.Urls.First() + "/admin/traffic-watch";
                var uri = new Uri(url.ToWebSocketPath());

                await client.ConnectAsync(uri, CancellationToken.None)
                .ConfigureAwait(false);


                // record traffic no more then 7 days
                var day     = 24 * 60 * 60;
                var timeout = (int)config.Timeout.TotalMilliseconds / 1000;
                timeout = Math.Min(timeout, 7 * day);
                if (timeout <= 0)
                {
                    timeout = 7 * day;
                }

                try
                {
                    string resourceName   = config.ResourceName ?? "N/A";
                    var    connectMessage = new DynamicJsonValue
                    {
                        ["Id"]           = id,
                        ["DatabaseName"] = resourceName,
                        ["Timeout"]      = timeout
                    };

                    var stream = new MemoryStream();

                    JsonOperationContext context;
                    using (_jsonContextPool.AllocateOperationContext(out context))
                        using (var writer = new BlittableJsonTextWriter(context, stream))
                        {
                            context.Write(writer, connectMessage);
                            writer.Flush();

                            ArraySegment <byte> bytes;
                            stream.TryGetBuffer(out bytes);
                            await client.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None)
                            .ConfigureAwait(false);
                        }

                    var requestsCounter = 0;
                    using (var fileStream = File.Create(config.RecordFilePath))
                    {
                        Stream finalStream = fileStream;
                        if (config.IsCompressed)
                        {
                            finalStream = new GZipStream(fileStream, CompressionMode.Compress, leaveOpen: true);
                        }

                        using (var streamWriter = new StreamWriter(finalStream))
                        {
                            var jsonWriter = new JsonTextWriter(streamWriter)
                            {
                                Formatting = Formatting.Indented
                            };
                            jsonWriter.WriteStartArray();
                            var sp = Stopwatch.StartNew();

                            while (true)
                            {
                                using (var reader = await Receive(client, context))
                                {
                                    if (reader == null)
                                    {
                                        // server asked to close connection
                                        break;
                                    }

                                    string type;
                                    if (reader.TryGet("Type", out type))
                                    {
                                        if (type.Equals("Heartbeat"))
                                        {
                                            continue;
                                        }
                                    }

                                    string error;
                                    if (reader.TryGet("Error", out error))
                                    {
                                        throw new InvalidOperationException("Server returned error: " + error);
                                    }

                                    var notification = new TrafficWatchChange();
                                    notification.TimeStamp           = GetDateTimeFromJson(reader, "TimeStamp");
                                    notification.RequestId           = GetIntFromJson(reader, "RequestId");
                                    notification.HttpMethod          = GetStringFromJson(reader, "HttpMethod");
                                    notification.ElapsedMilliseconds = GetIntFromJson(reader, "ElapsedMilliseconds");
                                    notification.ResponseStatusCode  = GetIntFromJson(reader, "ResponseStatusCode");
                                    notification.TenantName          = GetStringFromJson(reader, "TenantName");
                                    notification.CustomInfo          = GetStringFromJson(reader, "CustomInfo");
                                    notification.InnerRequestsCount  = GetIntFromJson(reader, "InnerRequestsCount");
                                    // notification.QueryTimings = GetRavenJObjectFromJson(reader, "QueryTimings"); // TODO (TrafficWatch) : Handle this both server and client sides

                                    if (config.PrintOutput)
                                    {
                                        Console.Write("\rRequest #{0} Stored...\t\t ", ++requestsCounter);
                                    }

                                    var jobj = JObject.FromObject(notification);
                                    jobj.WriteTo(jsonWriter);

                                    if (sp.ElapsedMilliseconds > 5000)
                                    {
                                        streamWriter.Flush();
                                        sp.Restart();
                                    }
                                }
                            }
                            jsonWriter.WriteEndArray();
                            streamWriter.Flush();
                            if (config.IsCompressed)
                            {
                                finalStream.Dispose();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("\r\n\nError while reading messages from server : " + ex);
                }
                finally
                {
                    Console.WriteLine("\r\n\nClosing connection to server...`");
                    try
                    {
                        await
                        client.CloseAsync(WebSocketCloseStatus.NormalClosure, "CLOSE_NORMAL", CancellationToken.None)
                        .ConfigureAwait(false);
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
        }
Ejemplo n.º 8
0
 public void EnqueMsg(TrafficWatchChange msg)
 {
     _msgs.Enqueue(msg);
     _manualResetEvent.Set();
 }
Ejemplo n.º 9
0
        private async Task RequestHandler(HttpContext context)
        {
            try
            {
                context.Response.StatusCode = (int)HttpStatusCode.OK;
                context.Response.Headers["Content-Type"] = "application/json; charset=utf-8";

                var sp       = Stopwatch.StartNew();
                var database = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value);

                sp.Stop();

                if (_logger.IsInfoEnabled && SkipHttpLogging == false)
                {
                    _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms");
                }

                if (TrafficWatchManager.HasRegisteredClients)
                {
                    var requestId = Interlocked.Increment(ref _requestId);

                    var twn = new TrafficWatchChange
                    {
                        TimeStamp           = DateTime.UtcNow,
                        RequestId           = requestId,                       // counted only for traffic watch
                        HttpMethod          = context.Request.Method ?? "N/A", // N/A ?
                        ElapsedMilliseconds = sp.ElapsedMilliseconds,
                        ResponseStatusCode  = context.Response.StatusCode,
                        RequestUri          = context.Request.GetEncodedUrl(),
                        AbsoluteUri         = $@"{context.Request.Scheme}://{context.Request.Host}",
                        DatabaseName        = database ?? "N/A",
                        CustomInfo          = "",  // TODO: Implement
                        InnerRequestsCount  = 0,   // TODO: Implement
                        QueryTimings        = null // TODO: Implement
                    };

                    TrafficWatchManager.DispatchMessage(twn);
                }
            }
            catch (Exception e)
            {
                if (context.RequestAborted.IsCancellationRequested)
                {
                    return;
                }

                //TODO: special handling for argument exception (400 bad request)
                //TODO: operation canceled (timeout)
                //TODO: Invalid data exception 422


                //TODO: Proper json output, not like this
                var response = context.Response;

                MaybeSetExceptionStatusCode(response, e);

                using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx))
                {
                    var djv = new DynamicJsonValue
                    {
                        [nameof(ExceptionDispatcher.ExceptionSchema.Url)]     = $"{context.Request.Path}{context.Request.QueryString}",
                        [nameof(ExceptionDispatcher.ExceptionSchema.Type)]    = e.GetType().FullName,
                        [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message
                    };


#if EXCEPTION_ERROR_HUNT
                    var f = Guid.NewGuid() + ".error";
                    File.WriteAllText(f,
                                      $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString);
#endif
                    djv[nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString();

                    MaybeAddAdditionalExceptionData(djv, e);

                    using (var writer = new BlittableJsonTextWriter(ctx, response.Body))
                    {
                        var json = ctx.ReadObject(djv, "exception");
                        writer.WriteObject(json);
                    }

#if EXCEPTION_ERROR_HUNT
                    File.Delete(f);
#endif
                }
            }
        }