示例#1
0
        public async Task <List <LogItemDto> > GetContainerLogs(string containerId, int numberOfLines)
        {
            var containerLogsParameters = new ContainerLogsParameters
            {
                Tail       = numberOfLines.ToString(),
                Follow     = false,
                Since      = null,
                ShowStdout = true,
                ShowStderr = true,
                Timestamps = false
            };

            var stream = await _client.Containers.GetContainerLogsAsync(containerId, containerLogsParameters);

            var logs = new List <LogItemDto>();

            using (var reader = new StreamReader(stream))
            {
                string line;
                // ToDo: Optimize this regex for SPEED
                var rgx = new Regex("(time=\"(?<Time>[\\d|\\-|TZ|\\:]+)\")?\\s(level=(?<Level>panic|fatal|error|warning|info|debug))?\\s(msg=\"(?<Message>.+)\")?", RegexOptions.ExplicitCapture);

                while ((line = reader.ReadLine()) != null)
                {
                    var matches = rgx.Match(line);
                    logs.Add(new LogItemDto
                    {
                        Date    = matches.Groups["Time"].Captures.First().Value,
                        Level   = matches.Groups["Level"].Captures.First().Value,
                        Message = matches.Groups["Message"].Captures.First().Value,
                    });
                }
            }
            return(logs);
        }
示例#2
0
        public async Task GetModuleLogsTest()
        {
            // Arrange
            string id        = "mod1";
            string dummyLogs = new string('*', 1000);

            Stream GetLogsStream() => new MemoryStream(Encoding.UTF8.GetBytes(dummyLogs));

            var systemInfoResponse = new SystemInfoResponse
            {
                OSType       = OperatingSystemType,
                Architecture = Architecture
            };

            ContainerLogsParameters receivedContainerLogsParameters = null;
            var containerOperations = new Mock <IContainerOperations>();

            containerOperations.Setup(co => co.GetContainerLogsAsync(id, It.IsAny <ContainerLogsParameters>(), It.IsAny <CancellationToken>()))
            .Callback <string, ContainerLogsParameters, CancellationToken>((m, c, t) => receivedContainerLogsParameters = c)
            .ReturnsAsync(GetLogsStream);

            var dockerClient = Mock.Of <IDockerClient>(
                dc =>
                dc.Containers == containerOperations.Object &&
                dc.System == Mock.Of <ISystemOperations>(so => so.GetSystemInfoAsync(default(CancellationToken)) == Task.FromResult(systemInfoResponse)));
            var runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(dockerClient);

            // Act
            Stream receivedLogsStream = await runtimeInfoProvider.GetModuleLogs(id, false, Option.None <int>(), CancellationToken.None);

            // Assert
            Assert.NotNull(receivedContainerLogsParameters);
            Assert.False(receivedContainerLogsParameters.Follow);
            Assert.Null(receivedContainerLogsParameters.Tail);
            Assert.True(receivedContainerLogsParameters.ShowStderr);
            Assert.True(receivedContainerLogsParameters.ShowStdout);
            var buffer    = new byte[1024];
            int readBytes = await receivedLogsStream.ReadAsync(buffer);

            Assert.Equal(1000, readBytes);
            string receivedLogs = Encoding.UTF8.GetString(buffer, 0, readBytes);

            Assert.Equal(dummyLogs, receivedLogs);

            // Act
            receivedLogsStream = await runtimeInfoProvider.GetModuleLogs(id, true, Option.Some(1000), CancellationToken.None);

            // Assert
            Assert.NotNull(receivedContainerLogsParameters);
            Assert.True(receivedContainerLogsParameters.Follow);
            Assert.Equal("1000", receivedContainerLogsParameters.Tail);
            Assert.True(receivedContainerLogsParameters.ShowStderr);
            Assert.True(receivedContainerLogsParameters.ShowStdout);
            buffer    = new byte[1024];
            readBytes = await receivedLogsStream.ReadAsync(buffer);

            Assert.Equal(1000, readBytes);
            receivedLogs = Encoding.UTF8.GetString(buffer, 0, readBytes);
            Assert.Equal(dummyLogs, receivedLogs);
        }
示例#3
0
文件: Docker.cs 项目: lie112/ApsimX
        /// <summary>
        /// Create a task to monitor the stdout and/or stderr streams from a
        /// running container, and invoke the given callback whenever data is
        /// written to the stream(s).
        /// </summary>
        /// <param name="id">ID of the container.</param>
        /// <param name="stdout">Monitor the container's stdout stream?</param>
        /// <param name="stderr">Monitor the container's stderr stream?</param>
        /// <param name="handler">Message callback.</param>
        /// <param name="cancelToken">Cancellation tokne.</param>
        private async Task WatchOutputStreamsAsync(string id, bool stdout, bool stderr, Action <string> handler, CancellationToken cancelToken)
        {
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            ContainerLogsParameters logParameters = new ContainerLogsParameters()
            {
                ShowStdout = stdout,
                ShowStderr = stderr,
                Follow     = true
            };
            Progress <string> callback = new Progress <string>(msg =>
            {
                try
                {
                    handler(msg);
                }
                catch (Exception error)
                {
                    Console.WriteLine($"Error in output callback:\n{error}");
                }
            });
            await client.Containers.GetContainerLogsAsync(id, logParameters, cancelToken, callback);
        }
示例#4
0
 public Task GetContainerLogsAsync(string id, ContainerLogsParameters parameters, CancellationToken cancellationToken, IProgress <string> progress)
 {
     return(StreamUtil.MonitorStreamAsync(
                GetContainerLogsAsync(id, parameters, cancellationToken),
                this._client,
                cancellationToken,
                progress));
 }
示例#5
0
        public async Task <string> GetContainerLogsAsync(ContainerLogsParameters logsParameters)
        {
            var stream = await _client.Containers.GetContainerLogsAsync(_createContainerResponse.ID, logsParameters);

            var streamReader = new StreamReader(stream, Encoding.UTF8);
            var result       = await streamReader.ReadToEndAsync();

            return(result);
        }
示例#6
0
        public async Task SuckAsync(CancellationToken cancellationToken)
        {
            DateTime?lastTimestamp = null;

            while (!cancellationToken.IsCancellationRequested)
            {
                var parameters = new ContainerLogsParameters()
                {
                    ShowStderr = true,
                    ShowStdout = true,
                    Follow     = true,
                    Timestamps = true,
                };

                //We don't want to keep getting the same old log entries, so we grab this.
                if (lastTimestamp != null)
                {
                    parameters.Since = (lastTimestamp.Value.Add(TimeSpan.FromSeconds(LogSlewSeconds)).ToUnixEpochTime()).ToString();
                }

                try
                {
                    using (var logStream = await _dockerClient.Containers.GetContainerLogsAsync(DockerContainerNames.Application, parameters, cancellationToken))
                        using (var streamReader = new LogStreamReader(logStream))
                        {
                            //Read the log event
                            DockerLogEvent logEvent = await streamReader.ReadAsync(cancellationToken);

                            //When this is null, the stream is to be closed.
                            while (logEvent != null)
                            {
                                //Keep track of this so we don't keep sucking down the same log entries.
                                lastTimestamp = logEvent.TimestampUtc;

                                //Add this to the collector.
                                await _batchCollector.AddAsync(logEvent);

                                logEvent = await streamReader.ReadAsync(cancellationToken);
                            }
                        }

                    _logger.Verbose("Application log stream closed.");
                }
                catch (TaskCanceledException)
                {
                }
                catch (Exception ex)
                {
                    _logger.Verbose("Exception occurred: {Message}", ex.Message);
                }

                await Task.Delay(TimeSpan.FromSeconds(RetrySeconds), cancellationToken);
            }
        }
示例#7
0
文件: Docker.cs 项目: lie112/ApsimX
        /// <summary>
        /// Read and return container logs as a tuple of (stdout, stderr).
        /// </summary>
        /// <param name="id">Container ID.</param>
        /// <param name="tty">Was the container started with TTY enabled?</param>
        /// <param name="cancelToken">Cancellation token.</param>
        private async Task <(string, string)> GetContainerLogsAsync(string id, bool tty, CancellationToken cancelToken)
        {
            ContainerLogsParameters logParameters = new ContainerLogsParameters()
            {
                ShowStdout = true,
                ShowStderr = true,
                Follow     = false
            };

            using (MultiplexedStream logStream = await client.Containers.GetContainerLogsAsync(id, tty, logParameters, cancelToken))
                return(await logStream.ReadOutputToEndAsync(cancelToken));
        }
        public async Task <Stream> GetLogs(bool follow, string tail)
        {
            var para = new ContainerLogsParameters()
            {
                ShowStderr = true,
                ShowStdout = true,
                Follow     = follow,
                Tail       = tail
            };

            return(await this.client.Containers.GetContainerLogsAsync(await this.ContainerId(), para, this.cancelTokenSource.Token));
        }
示例#9
0
        public Task <Stream> GetModuleLogs(string module, bool follow, Option <int> tail, CancellationToken cancellationToken)
        {
            var containerLogsParameters = new ContainerLogsParameters
            {
                Follow     = follow,
                ShowStderr = true,
                ShowStdout = true
            };

            tail.ForEach(t => containerLogsParameters.Tail = t.ToString());
            return(this.client.Containers.GetContainerLogsAsync(module, containerLogsParameters, cancellationToken));
        }
示例#10
0
        public Task <Stream> GetModuleLogs(string module, bool follow, Option <int> tail, Option <string> since, Option <string> until, Option <bool> includeTimestamp, CancellationToken cancellationToken)
        {
            var containerLogsParameters = new ContainerLogsParameters
            {
                Follow     = follow,
                ShowStderr = true,
                ShowStdout = true
            };

            tail.ForEach(t => containerLogsParameters.Tail   = t.ToString());
            since.ForEach(t => containerLogsParameters.Since = t.ToString());
            includeTimestamp.ForEach(t => containerLogsParameters.Timestamps = t);

            return(this.client.Containers.GetContainerLogsAsync(module, containerLogsParameters, cancellationToken));
        }
        public static async Task <string> GetEntireContainerLogAsync(this IContainerOperations containerOperations, string containerId)
        {
            ContainerLogsParameters logParameters = new ContainerLogsParameters
            {
                ShowStdout = true,
                ShowStderr = true,
                Follow     = false
            };

            using (Stream logStream = await containerOperations.GetContainerLogsAsync(containerId, logParameters, CancellationToken.None))
                using (StreamReader logReader = new StreamReader(logStream))
                {
                    return(logReader.ReadToEnd() ?? String.Empty);
                }
        }
示例#12
0
        public Task <Stream> GetContainerLogsAsync(string id, ContainerLogsParameters parameters, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            IQueryString queryParameters = new QueryString <ContainerLogsParameters>(parameters);

            return(this._client.MakeRequestForStreamAsync(new[] { NoSuchContainerHandler }, HttpMethod.Get, $"containers/{id}/logs", queryParameters, null, cancellationToken));
        }
示例#13
0
        /// <summary>
        ///     Create a new <see cref="GetContainerLogs"/> message.
        /// </summary>
        /// <param name="containerId">
        ///     The Id of the target container.
        /// </param>
        /// <param name="parameters">
        ///     <see cref="ContainerLogsParameters"/> used to control operation behaviour.
        /// </param>
        /// <param name="correlationId">
        ///     An optional message correlation Id (ContainerLogEntry messages will be delivered with this correlation Id).
        /// </param>
        public GetContainerLogs(string containerId, ContainerLogsParameters parameters, string correlationId = null)
            : base(correlationId)
        {
            if (String.IsNullOrWhiteSpace(containerId))
            {
                throw new ArgumentException($"Argument cannot be null, empty, or entirely composed of whitespace: {nameof(containerId)}.", nameof(containerId));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            ContainerId = containerId;
            Parameters  = parameters;
        }
示例#14
0
        private static async Task <string> ConsumeLogs(
            IImageSettings settings, TimeSpan timeout)
        {
            var containerStatsParameters = new ContainerLogsParameters
            {
                Follow     = true,
                ShowStderr = true,
                ShowStdout = true
            };

            Stream logStream = await _client
                               .Containers
                               .GetContainerLogsAsync(
                settings.ContainerId,
                containerStatsParameters,
                CancellationToken.None);

            return(await ReadAsync(logStream, timeout));
        }
        public async Task EnableLogs(string containerId)
        {
            ContainerLogsParameters logsParameters = new ContainerLogsParameters();

            logsParameters.Follow     = true;
            logsParameters.ShowStdout = true;
            logsParameters.ShowStderr = true;
            logsParameters.Tail       = "1000";
            logsParameters.Timestamps = true;
            Stream stream = await client.Containers.GetContainerLogsAsync(containerId, logsParameters, CancellationToken.None);

            lock (monitor)
            {
                DockerLogReader reader;
                if (logReaders.TryGetValue(containerId, out reader))
                {
                    reader.Stop();
                }
                logReaders[containerId] = new DockerLogReader(this, containerId, stream);
            }
        }
示例#16
0
        async Task TailLogsAsync(long exitCode)
        {
            Logger.LogError($"Module {this.module.Name} exited with a non-zero exit code of {exitCode}.");

            try
            {
                using (var cts = new CancellationTokenSource())
                {
                    var parameters = new ContainerLogsParameters
                    {
                        ShowStdout = true,
                        Tail       = LogLinesToPull
                    };
                    cts.CancelAfter(WaitForLogs);
                    using (Stream stream = await this.client.Containers.GetContainerLogsAsync(this.module.Name, parameters, cts.Token))
                    {
                        bool firstLine = true;
                        using (var reader = new StreamReader(stream))
                        {
                            while (stream.CanRead && !reader.EndOfStream)
                            {
                                if (firstLine)
                                {
                                    Logger.LogError($"Last {LogLinesToPull} log lines from container {this.module.Name}:");
                                    firstLine = false;
                                }

                                string line = await reader.ReadLineAsync();

                                Logger.LogError(line);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError($"Unable to get logs from module {this.module.Name} - {ex.Message}");
            }
        }
        /// <inheritdoc/>
        public async Task <string> ConsumeLogsAsync(TimeSpan timeout)
        {
            var containerStatsParameters = new ContainerLogsParameters
            {
                Follow     = true,
                ShowStderr = true,
                ShowStdout = true
            };

            Stream logStream = await _client
                               .Containers
                               .GetContainerLogsAsync(
                Instance.Id,
                containerStatsParameters,
                default);

            var logs = await ReadAsync(logStream, timeout);

            Instance.Logs.Add(logs);
            Trace.TraceInformation(logs);
            return(logs);
        }
示例#18
0
        public void WaitUntilTextFoundInLog(ContainerLogsParameters containerLogsParameters, string textToFind, int getLogsRetryCount, TimeSpan getLogsWaitTime)
        {
            Console.WriteLine($"Waiting keyword on log of {this.CreateResponse.ID}");

            if (!string.IsNullOrWhiteSpace(textToFind))
            {
                string logs = null;
                bool   isOk = false;
                for (int i = 0; i < getLogsRetryCount; i++)
                {
                    System.Threading.Thread.Sleep(getLogsWaitTime);

                    using (System.IO.Stream logStream = this.Docker.Containers.GetContainerLogsAsync(this.CreateResponse.ID, containerLogsParameters).GetAwaiter().GetResult())
                    {
                        using (System.IO.StreamReader reader = new System.IO.StreamReader(logStream))
                        {
                            logs = reader.ReadToEnd();
                        }
                        if (!string.IsNullOrWhiteSpace(logs))
                        {
                            isOk = logs.Contains(textToFind);
                            if (isOk)
                            {
                                break;
                            }
                            Console.WriteLine($"Keyword not found yet...");
                        }
                    }
                }
                if (!isOk)
                {
                    throw new TimeoutException("Timeout waiting logs");
                }
            }
            Console.WriteLine($"Ok, keyword found on log of {this.CreateResponse.ID}");
        }
示例#19
0
        public static async Task <long> Execute(string containerId, string filename, string logFilename)
        {
            Trace.WriteLine($"Initializing docker client");

            using (var config = DockerClientConfigurationFactory.Create())
                using (var client = config.CreateClient())
                {
                    var createArgs = new ContainerExecCreateParameters
                    {
                        AttachStdin  = true,
                        AttachStdout = true,

                        // psql -U postgres -f home/path/script.sql -v ON_ERROR_STOP=1
                        Cmd = new List <string>()
                        {
                            //"bash",
                            //"/usr/lib/postgresql/11/bin/psql",
                            "touch /home/test.txt",
                            //"-U postgres",
                            //@"-c \'l'"
                            //"-e",
                            //$"-f {filename}",
                            //$"-L {logFilename}",
                            //"-v",
                            //"ON_ERROR_STOP=1"
                        },
                        Tty          = false,
                        AttachStderr = true,
                        Detach       = false,
                        //Privileged = true
                    };

                    Trace.WriteLine($"exec create for container {containerId}");
                    var created = await client.Containers.ExecCreateContainerAsync(containerId, createArgs);

                    Trace.WriteLine($"starting container execution for created id {created.ID}");
                    await client.Containers.StartContainerExecAsync(created.ID);

                    ContainerExecInspectResponse result;

                    do
                    {
                        /*
                         * psql returns 0 to the shell if it finished normally,
                         * 1 if a fatal error of its own occurs (e.g. out of memory, file not found),
                         * 2 if the connection to the server went bad and the session was not interactive,
                         * and 3 if an error occurred in a script and the variable ON_ERROR_STOP was set.
                         */
                        result = await client.Containers.InspectContainerExecAsync(created.ID);

                        Trace.WriteLine($"Inspect result => Pid: {result.Pid}, running: {result.Running}, exit code: {result.ExitCode}");

                        var logArgs = new ContainerLogsParameters
                        {
                            ShowStderr = true,
                            ShowStdout = true
                        };

                        using (var logStream = await client.Containers.GetContainerLogsAsync(containerId, logArgs))
                            using (var reader = new StreamReader(logStream))
                            {
                                var logs = reader.ReadToEnd();
                                Trace.WriteLine(logs);
                            }

                        await Task.Delay(250);
                    } while (result.Running);

                    return(result.ExitCode);
                }
        }
        public async Task <MultiplexedStream> GetContainerLogsAsync(string id, bool tty, ContainerLogsParameters parameters, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            IQueryString queryParameters = new QueryString <ContainerLogsParameters>(parameters);

            Stream result = await this._client.MakeRequestForStreamAsync(new[] { NoSuchContainerHandler }, HttpMethod.Get, $"containers/{id}/logs", queryParameters, cancellationToken).ConfigureAwait(false);

            return(new MultiplexedStream(result, !tty));
        }
        private static async Task <string> WriteLog(DockerClient client, CreateContainerResponse container, ContainerLogsParameters op, CancellationToken token)
        {
            var log = await client.Containers.GetContainerLogsAsync(container.ID, op, token);

            var sb = new StringBuilder();

            using (var reader = new StreamReader(log))
            {
                while (!reader.EndOfStream)
                {
                    var line = await reader.ReadLineAsync();

                    if (op.ShowStderr.HasValue && op.ShowStderr.Value)
                    {
                        Console.WriteLine(line);
                    }
                    sb.AppendLine(line.TrimEnd(Environment.NewLine.ToCharArray()));
                }
            }
            return(sb.ToString());
        }
        public void DatabaseIntegratedTest(string dbTechnology)
        {
            bool isUnderContainer = (System.Environment.OSVersion.Platform == PlatformID.Unix);

            string buildTag = Environment.GetEnvironmentVariable("BUILD_TAG") ?? "jenkins-oragon-oragon-github-Oragon.Contexts-LOCAL-1";

            Oragon.Spring.Context.Support.XmlApplicationContext context = new Oragon.Spring.Context.Support.XmlApplicationContext("assembly://Oragon.Context.Tests/Oragon.Context.Tests.Integrated/DatabaseIntegrationTests.docker.xml");

            Skip.IfNot(context.ContainsObject($"{dbTechnology}.CreateContainerParameters"), "Has no configuration about " + dbTechnology);

            TimeSpan dockerDefaultTimeout = context.GetObject <TimeSpan>($"{dbTechnology}.DefaultTimeout");

            int getLogsRetryCount = context.GetObject <int>($"{dbTechnology}.GetLogsRetryCount");

            string textTofound = context.GetObject <string>($"{dbTechnology}.ExpectedText");

            TimeSpan getLogsWaitTime = context.GetObject <TimeSpan>($"{dbTechnology}.GetLogsWaitTime");

            CreateContainerParameters createContainerParameters = context.GetObject <CreateContainerParameters>($"{dbTechnology}.CreateContainerParameters");

            ContainerStartParameters containerStartParameters = context.GetObject <ContainerStartParameters>($"{dbTechnology}.ContainerStartParameters");

            ContainerLogsParameters containerLogsParameters = context.GetObject <ContainerLogsParameters>($"{dbTechnology}.ContainerLogsParameters");

            //Convention - If runnig outside docker, need expose port to perform the test
            createContainerParameters.HostConfig.PublishAllPorts = !isUnderContainer;

            using (DockerClient docker = new DockerClientConfiguration(this.GetEndpoint()).CreateClient())
            {
                //testing connectivity
                docker.DefaultTimeout = dockerDefaultTimeout;

                using (NetworkManager network = new NetworkManager(docker))
                {
                    network.Create(buildTag);

                    using (ContainerManager container = new ContainerManager(docker))
                    {
                        container.Create(createContainerParameters);

                        if (container.Start(containerStartParameters))
                        {
                            network.Connect(container, dbTechnology);

                            container.WaitUntilTextFoundInLog(containerLogsParameters, textTofound, 10, getLogsWaitTime);

                            ContainerInspectResponse containerInfo = container.Inspect();

                            string portKey = createContainerParameters.ExposedPorts.Keys.Single();
                            string dbPort, dbHostname;

                            ContainerManager jenkinsTestContainer = null;

                            if (!isUnderContainer)
                            {
                                dbPort     = containerInfo.NetworkSettings.Ports[portKey].Single().HostPort;
                                dbHostname = "127.0.0.1";
                            }
                            else
                            {
                                jenkinsTestContainer = ContainerManager.GetCurrent(docker) ?? throw new InvalidOperationException("ContainerManager.GetCurrent result nothing");

                                network.Connect(jenkinsTestContainer, "jenkins_worker");

                                dbPort = portKey.Split('/', StringSplitOptions.RemoveEmptyEntries).First();

                                dbHostname = dbTechnology;
                            }

                            try
                            {
                                this.DatabaseIntegratedTestInternal(dbTechnology, dbHostname, dbPort);
                            }
                            finally
                            {
                                if (jenkinsTestContainer != null)
                                {
                                    network.Disconnect(jenkinsTestContainer);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#23
0
        static async Task Main(string[] args)
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                _client = new DockerClientConfiguration(new Uri("unix:///var/run/docker.sock")).CreateClient();
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                _client = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")).CreateClient();
            }

            IList <ContainerListResponse> containers = await _client.Containers.ListContainersAsync(
                new ContainersListParameters()
            {
                Limit = 10,
            });

            ContainerListResponse        edgeAgent   = null;
            List <ContainerListResponse> edgeModules = new List <ContainerListResponse>();

            foreach (var container in containers)
            {
                foreach (var label in container.Labels)
                {
                    if (label.Key.Contains("net.azure-devices.edge.owner"))
                    {
                        edgeModules.Add(container);
                    }
                }

                // edge case due to bug (no pun intended)
                if (container.Names.First() == "/edgeAgent")
                {
                    edgeAgent = container;
                    break;
                }
                Console.WriteLine($"{container.ID}");
            }

            TelemetryClient telemetry = new TelemetryClient();

            telemetry.InstrumentationKey = "";

            string containerName = "iotlogs";
            string blobName      = string.Format("{0}-{1}{2}", edgeAgent.Names.First().TrimStart('/'), DateTime.UtcNow.ToString("yyyy-MM-dd-hh-mm-ss"), ".log");
            string accountName   = "";
            string keyValue      = "";

            StorageCredentials  creds         = new StorageCredentials(accountName, keyValue);
            CloudStorageAccount account       = new CloudStorageAccount(creds, true);
            CloudBlobClient     blobClient    = account.CreateCloudBlobClient();
            CloudBlobContainer  blobContainer = blobClient.GetContainerReference(containerName);

            try
            {
                BlobRequestOptions requestOptions = new BlobRequestOptions()
                {
                    RetryPolicy = new NoRetry()
                };
                await blobContainer.CreateIfNotExistsAsync(requestOptions, null);
            }
            catch (StorageException)
            {
                Console.WriteLine("If you are running with the default connection string, please make sure you have started the storage emulator. Press the Windows key and type Azure Storage to select and run it from the list of applications - then restart the sample.");
                Console.ReadLine();
                throw;
            }

            CloudAppendBlob blockBlob = blobContainer.GetAppendBlobReference(blobName);

            ContainerLogsParameters logsParameters = new ContainerLogsParameters()
            {
                ShowStderr = true, ShowStdout = true, Follow = true
            };
            Stream logs = await _client.Containers.GetContainerLogsAsync(edgeAgent.ID, logsParameters, CancellationToken.None);

            List <string> logdata = new List <string>();

            using (StreamReader reader = new StreamReader(logs))
            {
                string line;
                while (true)
                {
                    line = await reader.ReadLineAsync();

                    if (!string.IsNullOrEmpty(line))
                    {
                        logdata.Add(line);
                        Console.WriteLine(line);
                    }

                    if (logdata.Count > 500)
                    {
                        if (useStorage)
                        {
                            Console.WriteLine("Uploading...");
                            string data = string.Join(System.Environment.NewLine, logdata);
                            await blockBlob.CreateOrReplaceAsync();

                            try
                            {
                                await blockBlob.AppendTextAsync(data);
                            }
                            catch (System.Exception up)
                            {
                                throw up;
                            }

                            logdata.Clear();
                        }
                        else
                        {
                            Console.WriteLine("Uploading...");

                            try
                            {
                                foreach (var msg in logdata)
                                {
                                    telemetry.TrackTrace(msg);
                                }
                            }
                            catch (System.Exception up)
                            {
                                throw up;
                            }

                            logdata.Clear();
                        }
                    }
                }
            }
        }