/// <summary>
 /// Create a new instance of <see cref="LoggerOptions"/>.
 /// </summary>
 /// <param name="logLevel">Optional, the minimum log level.  Defaults to <see cref="LogLevel.Information"/></param>
 /// <param name="monitoredResource">Optional, the monitored resource.  The monitored resource will
 ///     be automatically detected if it is not set and will default to the global resource if the detection fails.
 ///     See: https://cloud.google.com/logging/docs/api/v2/resource-list </param>
 /// <param name="bufferOptions">Optional, the buffer options.  Defaults to a <see cref="BufferType.Timed"/></param>
 public static LoggerOptions Create(LogLevel logLevel = LogLevel.Information,
                                    MonitoredResource monitoredResource = null, BufferOptions bufferOptions = null)
 {
     monitoredResource = monitoredResource ?? MonitoredResourceBuilder.FromPlatform();
     bufferOptions     = bufferOptions ?? BufferOptions.TimedBuffer();
     return(new LoggerOptions(logLevel, monitoredResource, bufferOptions));
 }
示例#2
0
        public void GetsLogViewingUrl()
        {
            TextWriter oldConsoleOut = Console.Out;
            string     writtenInfo;

            using (StringWriter writer = new StringWriter())
            {
                Console.SetOut(writer);

                // No need to make an actual call to the controller. Just starting up the server
                // creates several loggers.
                using (TestServer server = GetTestServer(GetUrlWriterHostBuilder())) { }

                writtenInfo = writer.ToString();

                Console.SetOut(oldConsoleOut);
            }

            int urlStart = writtenInfo.LastIndexOf("http", StringComparison.OrdinalIgnoreCase);

            Assert.NotEqual(urlStart, -1);

            // We know the URL is the last to be written.
            string url             = writtenInfo.Substring(urlStart);
            string expectedProject = TestEnvironment.GetTestProjectId();

            Assert.StartsWith(ExpectedGcpLogBaseUrl, url);
            Assert.Contains($"resource={MonitoredResourceBuilder.FromPlatform().Type}", url);
            Assert.Contains($"project={expectedProject}", url);
            Assert.Contains("minLogLevel=200", url);
            Assert.Contains($"logName=projects/{expectedProject}/logs/aspnetcore", url);
            Assert.DoesNotContain("organizationId=", url);
        }
示例#3
0
        /// <summary>
        /// Writes a single "canary" log entry and waits for it to be visible. This is written
        /// after all the entries from tests, so by the time this is visible, it's "reasonably likely"
        /// that all the test log messages are also visible.
        /// </summary>
        private void LogCanaryMessageAndWait()
        {
            DateTime startTime = DateTime.UtcNow;
            string   id        = IdGenerator.FromGuid();
            LogEntry entry     = new LogEntry
            {
                Resource    = MonitoredResourceBuilder.FromPlatform(),
                LogName     = $"projects/{_projectId}/logs/aspnetcore",
                Severity    = Logging.Type.LogSeverity.Info,
                Timestamp   = Timestamp.FromDateTime(DateTime.UtcNow),
                JsonPayload = new Struct {
                    Fields = { ["message"] = Value.ForString(id) }
                }
            };

            _client.WriteLogEntries((LogName)null, null, null, new[] { entry });

            var request = BuildRequest(startTime);

            request.Filter += $" AND jsonPayload.message:\"{id}\"";

            // Wait for the canary log entry to be visible.
            var endTime = startTime + s_canaryMessageTimeout;

            while (DateTime.UtcNow < endTime)
            {
                FileLogger.Log("Listing log entries to find the canary");
                if (_client.ListLogEntries(request).Any())
                {
                    return;
                }
                Thread.Sleep(s_delayBetweenCanaryAttempts);
            }
            throw new Exception("Canary message never seen.");
        }
示例#4
0
        public void GetGcpConsoleLogsUrl_MonitoredResourceFromPlatform()
        {
            GoogleLogger logger = GetLogger(monitoredResource: MonitoredResourceBuilder.FromPlatform());
            string       query  = logger.GetGcpConsoleLogsUrl().Query;

            Assert.Contains($"resource={MonitoredResourceBuilder.FromPlatform().Type}", query);
        }
示例#5
0
        public void GkePlatform()
        {
            const string metadataJson   = @"
{
  'project': {
    'projectId': 'FakeProjectId'
  },
  'instance': {
    'attributes': {
      'cluster-name': 'FakeClusterName',
    },
    'id': '123',
    'zone': 'projects/FakeProject/zones/FakeLocation'
  }
}
";
            const string namespaceJson  = @"
{
  'kind': 'Namespace',
  'metadata': {
    'uid': 'namespaceid',
    'name':'namespacename'
  }
}
";
            const string podJson        = @"
{
  'kind': 'Pod',
  'metadata': {
    'name': 'podname',
    'uid': 'podid'
  }
}
";
            var          kubernetesData = new GkePlatformDetails.KubernetesData
            {
                NamespaceJson = namespaceJson,
                PodJson       = podJson,
                MountInfo     = new[] { "/var/lib/kubelet/pods/podid/containers/containername/ /dev/termination-log" }
            };
            var platform = new Platform(GkePlatformDetails.TryLoad(metadataJson, kubernetesData));
            var resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("container", resource.Type);
            Assert.Equal(new Dictionary <string, string>
            {
                { "project_id", "FakeProjectId" },
                { "cluster_name", "FakeClusterName" },
                // Although the name of the label is namespace_id, the actual value returned and expected
                // by Stackdriver is the namespace name.
                { "namespace_id", "namespacename" },
                { "instance_id", "123" },
                // Although the name of the label is pod_id, the actual value returned and expected
                // by Stackdriver is the pod name.
                { "pod_id", "podname" },
                { "container_name", "containername" },
                { "zone", "FakeLocation" }
            }, resource.Labels);
        }
示例#6
0
        // There are three different potential resource representations for GKE. We handle them all
        // the same way, but we need to test that.
        private static MonitoredResource CreateGkeResource(string resourceType)
        {
            var resource = MonitoredResourceBuilder.FromPlatform(new Platform(
                                                                     new GkePlatformDetails("json", "project-id", "cluster", "location", "host", "instance", "zone", "namespace", "pod", "container", "clusterLocation")));

            resource.Type = resourceType;
            return(resource);
        }
        public void UnknownPlatform()
        {
            var platform = new Platform();
            var resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("global", resource.Type);
            Assert.Empty(resource.Labels);
        }
        public void GetGcpConsoleLogsUrl_Gae()
        {
            GoogleLogger logger = GetLogger(monitoredResource: MonitoredResourceBuilder.FromPlatform(new Platform(
                                                                                                         new GaePlatformDetails("project-id", "instance", "service", "version"))));
            string query = logger.GetGcpConsoleLogsUrl().Query;

            Assert.Contains($"resource=gae_app", query);
        }
 /// <summary>
 /// Create a new instance of <see cref="LoggerOptions"/>.
 /// </summary>
 /// <param name="logLevel">Optional, the minimum log level.  Defaults to <see cref="LogLevel.Information"/></param>
 /// <param name="labels">Optional, custom labels to be added to log entries.</param>
 /// <param name="monitoredResource">Optional, the monitored resource.  The monitored resource will
 ///     be automatically detected if it is not set and will default to the global resource if the detection fails.
 ///     See: https://cloud.google.com/logging/docs/api/v2/resource-list </param>
 /// <param name="bufferOptions">Optional, the buffer options.  Defaults to a <see cref="BufferType.Timed"/></param>
 public static LoggerOptions Create(LogLevel logLevel = LogLevel.Information,
                                    Dictionary <string, string> labels  = null,
                                    MonitoredResource monitoredResource = null, BufferOptions bufferOptions = null)
 {
     labels            = labels ?? new Dictionary <string, string>();
     monitoredResource = monitoredResource ?? MonitoredResourceBuilder.FromPlatform();
     bufferOptions     = bufferOptions ?? BufferOptions.TimedBuffer();
     return(new LoggerOptions(logLevel, labels, monitoredResource, bufferOptions));
 }
        public void GkePlatform()
        {
            const string metadataJson   = @"
{
  'project': {
    'projectId': 'FakeProjectId'
  },
  'instance': {
    'attributes': {
      'cluster-name': 'FakeClusterName',
      'cluster-location': 'FakeClusterLocation'
    },
    'id': '123',
    'zone': 'projects/FakeProject/zones/FakeLocation'
  }
}
";
            const string namespaceJson  = @"
{
  'kind': 'Namespace',
  'metadata': {
    'uid': 'namespaceid',
    'name':'namespacename'
  }
}
";
            const string podJson        = @"
{
  'kind': 'Pod',
  'metadata': {
    'name': 'podname',
    'uid': 'podid'
  }
}
";
            var          kubernetesData = new GkePlatformDetails.KubernetesData
            {
                NamespaceJson = namespaceJson,
                PodJson       = podJson,
                MountInfo     = new[] { "1 2 3 /var/lib/kubelet/pods/podid/containers/containername/ /dev/termination-log xyz" }
            };
            var platform = new Platform(GkePlatformDetails.TryLoad(metadataJson, kubernetesData));
            var resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("k8s_container", resource.Type);
            Assert.Equal(new Dictionary <string, string>
            {
                { "project_id", "FakeProjectId" },
                { "cluster_name", "FakeClusterName" },
                { "namespace_name", "namespacename" },
                { "pod_name", "podname" },
                { "container_name", "containername" },
                { "location", "FakeClusterLocation" }
            }, resource.Labels);
        }
        public void GaePlatform()
        {
            var platform = new Platform(new GaePlatformDetails("FakeProjectId", "FakeInstanceId", "FakeService", "FakeVersion"));
            var resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("gae_app", resource.Type);
            Assert.Equal(3, resource.Labels.Count);
            Assert.Equal("FakeProjectId", resource.Labels["project_id"]);
            Assert.Equal("FakeService", resource.Labels["module_id"]);
            Assert.Equal("FakeVersion", resource.Labels["version_id"]);
        }
示例#12
0
 /// <summary>
 /// Creates a new <see cref="EventTarget"/> instance that will report to the Stackdriver Logging API.
 /// The events are then automatically propigated to the Stackdriver Error Logging API from the
 /// Stackdriver Logging API.
 /// </summary>
 /// <remarks>
 /// For more information see "Formatting Log Error Messages"
 /// (https://cloud.google.com/error-reporting/docs/formatting-error-messages).
 /// </remarks>
 /// <param name="logTarget">Where to log to, such as a project or organization. Cannot be null.</param>
 /// <param name="logName">The log name.  Cannot be null.</param>
 /// <param name="loggingClient">The logging client.</param>
 /// <param name="monitoredResource">Optional, the monitored resource.  The monitored resource will
 ///     be automatically detected if it is not set and will default to the global resource if the detection fails.
 ///     See: https://cloud.google.com/logging/docs/api/v2/resource-list </param>
 public static EventTarget ForLogging(LogTarget logTarget, string logName  = LogNameDefault,
                                      LoggingServiceV2Client loggingClient = null, MonitoredResource monitoredResource = null)
 {
     return(new EventTarget
     {
         Kind = EventTargetKind.Logging,
         LoggingClient = loggingClient ?? LoggingServiceV2Client.Create(),
         LogTarget = GaxPreconditions.CheckNotNull(logTarget, nameof(logTarget)),
         LogName = GaxPreconditions.CheckNotNullOrEmpty(logName, nameof(logName)),
         MonitoredResource = monitoredResource ?? MonitoredResourceBuilder.FromPlatform(),
     });
 }
        public void GaePlatform()
        {
            var platform = new Platform(new GaePlatformDetails("FakeProjectId", "FakeInstanceId", "FakeService", "FakeVersion"));
            var resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("gae_app", resource.Type);
            Assert.Equal(new Dictionary <string, string>
            {
                { "project_id", "FakeProjectId" },
                { "module_id", "FakeService" },
                { "version_id", "FakeVersion" }
            }, resource.Labels);
        }
示例#14
0
        private void ActivateLogIdAndResource(string logId)
        {
            // Project ID of the project where the resource that is being monitored lives.
            string monitoredProjectId = null;
            // Project ID of the project where the entries are to be written.
            string            targetProjectId = null;
            MonitoredResource resource        = null;

            if (!DisableResourceTypeDetection)
            {
                resource = MonitoredResourceBuilder.FromPlatform(_platform);
                resource.Labels.TryGetValue("project_id", out monitoredProjectId);
            }

            targetProjectId = ProjectId?.Render(LogEventInfo.CreateNullEvent());

            if (monitoredProjectId == null)
            {
                // Either platform detection is disabled, or it detected an unknown platform.
                // So use the manually configured projectId and override the resource.
                monitoredProjectId = GaxPreconditions.CheckNotNull(targetProjectId, nameof(ProjectId));
                if (ResourceType == null)
                {
                    resource = new MonitoredResource {
                        Type = "global", Labels = { { "project_id", monitoredProjectId } }
                    };
                }
                else
                {
                    resource = new MonitoredResource
                    {
                        Type   = ResourceType,
                        Labels = { ResourceLabels.ToDictionary(x => x.Name, x => x.Layout.Render(LogEventInfo.CreateNullEvent())) }
                    };
                }
            }

            if (targetProjectId == null)
            {
                // If there was no configured projectId, then use the same as the monitored resoure.
                targetProjectId = monitoredProjectId;
            }

            _resource = resource;
            var logName = new LogName(targetProjectId, logId);

            _logName           = logName.ToString();
            _logNameToWrite    = logName;
            _traceResourcePath = !string.IsNullOrEmpty(targetProjectId) ? $"projects/{targetProjectId}/traces/" : null;
        }
示例#15
0
 /// <summary>
 /// Create a new instance of <see cref="LoggerOptions"/>.
 /// </summary>
 /// <param name="logLevel">Optional, the minimum log level.  Defaults to <see cref="LogLevel.Information"/></param>
 /// <param name="logName">Optional, the name of the log.  Defaults to 'aspnetcore'.</param>
 /// <param name="labels">Optional, custom labels to be added to log entries.
 /// Keys and values added to <paramref name="labels"/> should not be null.
 /// If they are, an exception will be throw when attempting to log an entry.
 /// The entry won't be logged and the exception will be propagated depending
 /// on the value of <see cref="RetryOptions.ExceptionHandling"/>.</param>
 /// <param name="monitoredResource">Optional, the monitored resource.  The monitored resource will
 /// be automatically detected if it is not set and will default to the global resource if the detection fails.
 /// See: https://cloud.google.com/logging/docs/api/v2/resource-list </param>
 /// <param name="bufferOptions">Optional, the buffer options.  Defaults to a <see cref="BufferType.Timed"/></param>
 /// <param name="retryOptions">Optional, the retry options.  Defaults to a <see cref="RetryType.None"/></param>
 /// <param name="loggerDiagnosticsOutput">Optional. If set some logger diagnostics info will be written
 /// to the given <see cref="TextWriter"/>. Currently the only diagnostics info we provide is the URL where
 /// the logs written with these options can be found.</param>
 public static LoggerOptions Create(
     LogLevel logLevel = LogLevel.Information,
     string logName    = null,
     Dictionary <string, string> labels  = null,
     MonitoredResource monitoredResource = null,
     BufferOptions bufferOptions         = null,
     RetryOptions retryOptions           = null,
     TextWriter loggerDiagnosticsOutput  = null)
 {
     logName           = logName ?? _baseLogName;
     labels            = labels ?? new Dictionary <string, string>();
     monitoredResource = monitoredResource ?? MonitoredResourceBuilder.FromPlatform();
     bufferOptions     = bufferOptions ?? BufferOptions.TimedBuffer();
     retryOptions      = retryOptions ?? RetryOptions.NoRetry();
     return(new LoggerOptions(logLevel, logName, labels, monitoredResource, bufferOptions, retryOptions, loggerDiagnosticsOutput));
 }
        public void CloudRunPlatform()
        {
            var details  = new CloudRunPlatformDetails("json", "projectId", "us-central1-1", "service", "revision", "configuration");
            var resource = MonitoredResourceBuilder.FromPlatform(new Platform(details));

            Assert.Equal("cloud_run_revision", resource.Type);
            Assert.Equal(new Dictionary <string, string>
            {
                { "project_id", "projectId" },
                // Note this is the region, not the zone
                { "location", "us-central1" },
                { "service_name", "service" },
                { "revision_name", "revision" },
                { "configuration_name", "configuration" }
            }, resource.Labels);
        }
示例#17
0
        /// <summary>
        /// Determines the correct project id from a string project id and a <see cref="MonitoredResource"/>.
        /// If the specified project id is not null, it is returned. Otherwise, if the project id of
        /// the MonitoredResource is not null, it is returned. It both are null,
        /// an <see cref="InvalidOperationException"/> is thrown.
        /// </summary>
        /// <param name="projectId">The Google Cloud project ID.  Can be null.</param>
        /// <param name="monitoredResource">Optional, The monitored resource. If unset the monitored resource will
        ///     be auto detected.</param>
        /// <returns>The Google Cloud project ID.</returns>
        internal static string GetAndCheckProjectId(string projectId, MonitoredResource monitoredResource = null)
        {
            if (projectId != null)
            {
                return(projectId);
            }

            monitoredResource = monitoredResource ?? MonitoredResourceBuilder.FromPlatform();
            string resourceProjectId;

            if (monitoredResource.Labels.TryGetValue("project_id", out resourceProjectId))
            {
                return(resourceProjectId);
            }

            throw new InvalidOperationException("No Google Cloud project ID was passed in or detected.");
        }
示例#18
0
 /// <summary>
 /// Create a new instance of <see cref="LoggerOptions"/>.
 /// </summary>
 /// <param name="logLevel">Optional, the minimum log level.  Defaults to <see cref="LogLevel.Information"/></param>
 /// <param name="logName">Optional, the name of the log.  Defaults to 'aspnetcore'.</param>
 /// <param name="labels">Optional, custom labels to be added to log entries.
 /// Keys and values added to <paramref name="labels"/> should not be null.
 /// If they are, an exception will be throw when attempting to log an entry.
 /// The entry won't be logged and the exception will be propagated depending
 /// on the value of <see cref="RetryOptions.ExceptionHandling"/>.</param>
 /// <param name="monitoredResource">Optional, the monitored resource.  The monitored resource will
 /// be automatically detected if it is not set and will default to the global resource if the detection fails.
 /// See: https://cloud.google.com/logging/docs/api/v2/resource-list </param>
 /// <param name="bufferOptions">Optional, the buffer options.  Defaults to a <see cref="BufferType.Timed"/></param>
 /// <param name="retryOptions">Optional, the retry options.  Defaults to a <see cref="RetryType.None"/></param>
 /// <param name="loggerDiagnosticsOutput">Optional. If set some logger diagnostics info will be written
 /// to the given <see cref="TextWriter"/>. Currently the only diagnostics info we provide is the URL where
 /// the logs written with these options can be found.</param>
 /// <param name="serviceName">A string that represents the version of the service or the source code that logs are written for.
 /// When set, it will be included in the <code>serviceContext</code> field of the log entry JSON payload.</param>
 /// <param name="version">A string that represents the version of the service or the source code that logs are written for.
 /// When set, it will be included in the <code>serviceContext</code> field of the log entry JSON payload.</param>
 public static LoggerOptions CreateWithServiceContext(
     LogLevel logLevel = LogLevel.Information,
     string logName    = null,
     Dictionary <string, string> labels  = null,
     MonitoredResource monitoredResource = null,
     BufferOptions bufferOptions         = null,
     RetryOptions retryOptions           = null,
     TextWriter loggerDiagnosticsOutput  = null,
     string serviceName = null,
     string version     = null)
 {
     logName ??= _baseLogName;
     labels ??= new Dictionary <string, string>();
     monitoredResource ??= MonitoredResourceBuilder.FromPlatform();
     bufferOptions ??= BufferOptions.TimedBuffer();
     retryOptions ??= RetryOptions.NoRetry();
     return(new LoggerOptions(logLevel, logName, labels, monitoredResource, bufferOptions, retryOptions, loggerDiagnosticsOutput, serviceName, version));
 }
示例#19
0
        private void ActivateLogIdAndResource()
        {
            string            projectId = null;
            MonitoredResource resource  = null;

            if (!DisableResourceTypeDetection)
            {
                resource = MonitoredResourceBuilder.FromPlatform(_platform);
                resource.Labels.TryGetValue("project_id", out projectId);
            }
            if (projectId == null)
            {
                // Either platform detection is disabled, or it detected an unknown platform
                // So use the manually configured projectId and override the resource
                projectId = GaxPreconditions.CheckNotNull(ProjectId, nameof(ProjectId));
                if (ResourceType == null)
                {
                    resource = new MonitoredResource {
                        Type = "global", Labels = { { "project_id", projectId } }
                    };
                }
                else
                {
                    resource = new MonitoredResource {
                        Type = ResourceType, Labels = { _resourceLabels.ToDictionary(x => x.Key, x => x.Value) }
                    };
                }
            }
            else
            {
                if (ProjectId != null && projectId != ProjectId)
                {
                    _preLogs.Add(() => BuildLogEntry(new LoggingEvent(new LoggingEventData
                    {
                        Level      = Level.Warn,
                        LoggerName = "",
                        Message    = s_mismatchedProjectIdMessage,
                        TimeStamp  = _clock.GetCurrentDateTimeUtc()
                    })));
                }
            }
            _resource = resource;
            _logName  = new LogName(projectId, LogId).ToString();
        }
        public GoogleCloudLoggingSink(GoogleCloudLoggingSinkOptions sinkOptions, MessageTemplateTextFormatter messageTemplateTextFormatter, int batchSizeLimit, TimeSpan period)
            : base(batchSizeLimit, period)
        {
            _sinkOptions = sinkOptions;

            // logging client for google cloud apis
            // requires extra setup if credentials are passed as raw json text
            if (sinkOptions.GoogleCredentialJson == null)
            {
                _client = LoggingServiceV2Client.Create();
            }
            else
            {
                var googleCredential = GoogleCredential.FromJson(sinkOptions.GoogleCredentialJson);
                var channel          = new Grpc.Core.Channel(LoggingServiceV2Client.DefaultEndpoint.Host, googleCredential.ToChannelCredentials());
                _client = LoggingServiceV2Client.Create(channel);
            }

            // retrieve current environment details (gke/gce/appengine) from google libraries automatically
            // or fallback to "Global" resource
            var platform = Platform.Instance();

            _resource = platform.Type == PlatformType.Unknown
                ? MonitoredResourceBuilder.GlobalResource
                : MonitoredResourceBuilder.FromPlatform(platform);

            foreach (var kvp in _sinkOptions.ResourceLabels)
            {
                _resource.Labels[kvp.Key] = kvp.Value;
            }

            // use explicit ResourceType if set
            _resource.Type = sinkOptions.ResourceType ?? _resource.Type;

            // use explicit project ID or fallback to project ID found in platform environment details above
            var projectId = _sinkOptions.ProjectId ?? _resource.Labels["project_id"];

            _logName = LogFormatter.CreateLogName(projectId, sinkOptions.LogName);

            _serviceNameAvailable = !String.IsNullOrWhiteSpace(_sinkOptions.ServiceName);
            _logFormatter         = new LogFormatter(projectId, _sinkOptions.UseSourceContextAsLogName, messageTemplateTextFormatter);
        }
示例#21
0
        public GoogleCloudLoggingSink(GoogleCloudLoggingSinkOptions sinkOptions, MessageTemplateTextFormatter messageTemplateTextFormatter)
        {
            _sinkOptions = sinkOptions;

            // logging client for google cloud apis
            // requires extra setup if credentials are passed as raw json text
            if (sinkOptions.GoogleCredentialJson == null)
            {
                _client = LoggingServiceV2Client.Create();
            }
            else
            {
                _client = new LoggingServiceV2ClientBuilder {
                    JsonCredentials = sinkOptions.GoogleCredentialJson
                }.Build();
            }

            // retrieve current environment details (gke/gce/appengine) from google libraries automatically
            var platform = Platform.Instance();

            // resource can be extracted from environment details or fallback to "Global" resource
            _resource = platform.Type == PlatformType.Unknown
                ? MonitoredResourceBuilder.GlobalResource
                : MonitoredResourceBuilder.FromPlatform(platform);

            foreach (var kvp in _sinkOptions.ResourceLabels)
            {
                _resource.Labels[kvp.Key] = kvp.Value;
            }

            // use explicit ResourceType if set
            _resource.Type = sinkOptions.ResourceType ?? _resource.Type;

            // use explicit project ID or fallback to project ID found in platform environment details above
            var projectId = _sinkOptions.ProjectId ?? platform.ProjectId ?? _resource.Labels["project_id"];

            _logName              = LogFormatter.CreateLogName(projectId, sinkOptions.LogName);
            _logFormatter         = new LogFormatter(projectId, _sinkOptions.UseSourceContextAsLogName, messageTemplateTextFormatter);
            _serviceNameAvailable = !String.IsNullOrWhiteSpace(_sinkOptions.ServiceName);
        }
        public void GcePlatform()
        {
            const string json     = @"
{
  'project': {
    'projectId': 'FakeProjectId'
  },
  'instance': {
    'id': 'FakeInstanceId',
    'zone': 'FakeZone'
  }
}
";
            var          platform = new Platform(GcePlatformDetails.TryLoad(json));
            var          resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("gce_instance", resource.Type);
            Assert.Equal(3, resource.Labels.Count);
            Assert.Equal("FakeProjectId", resource.Labels["project_id"]);
            Assert.Equal("FakeInstanceId", resource.Labels["instance_id"]);
            Assert.Equal("FakeZone", resource.Labels["zone"]);
        }
        public async Task WritesLogsUrlAsync()
        {
            IHost      host          = null;
            TextWriter oldConsoleOut = Console.Out;

            try
            {
                using StringWriter writer = new StringWriter();
                Console.SetOut(writer);

                // No need to make an actual call to the controller. Just starting up the server
                // creates several loggers.
                host = WritesLogsUrlHostBuilder.CreateHostBuilder().Build();
                await host.StartAsync();

                string writtenInfo = writer.ToString();

                int urlStart = writtenInfo.LastIndexOf("http", StringComparison.OrdinalIgnoreCase);
                Assert.NotEqual(urlStart, -1);

                // We know the URL is the last to be written.
                string url = writtenInfo.Substring(urlStart);

                Assert.StartsWith(ExpectedGcpLogBaseUrl, url);
                Assert.Contains($"resource={MonitoredResourceBuilder.FromPlatform().Type}", url);
                Assert.Contains($"project={ProjectId}", url);
                Assert.Contains("minLogLevel=200", url);
                Assert.Contains($"logName=projects/{ProjectId}/logs/aspnetcore", url);
                Assert.DoesNotContain("organizationId=", url);
            }
            finally
            {
                Console.SetOut(oldConsoleOut);
                if (host is object)
                {
                    await host.StopAsync();
                }
            }
        }
示例#24
0
        private void ActivateLogIdAndResource(string logId)
        {
            string            projectId = null;
            MonitoredResource resource  = null;

            if (!DisableResourceTypeDetection)
            {
                resource = MonitoredResourceBuilder.FromPlatform(_platform);
                resource.Labels.TryGetValue("project_id", out projectId);
            }

            if (projectId == null)
            {
                // Either platform detection is disabled, or it detected an unknown platform.
                // So use the manually configured projectId and override the resource.
                projectId = GaxPreconditions.CheckNotNull(ProjectId?.Render(LogEventInfo.CreateNullEvent()), nameof(ProjectId));
                if (ResourceType == null)
                {
                    resource = new MonitoredResource {
                        Type = "global", Labels = { { "project_id", projectId } }
                    };
                }
                else
                {
                    resource = new MonitoredResource {
                        Type   = ResourceType,
                        Labels = { ResourceLabels.ToDictionary(x => x.Name, x => x.Layout.Render(LogEventInfo.CreateNullEvent())) }
                    };
                }
            }

            _resource = resource;
            var logName = new LogName(projectId, logId);

            _logName        = logName.ToString();
            _logNameToWrite = LogNameOneof.From(logName);
        }
        public void GcePlatform()
        {
            const string json     = @"
{
  'project': {
    'projectId': 'FakeProjectId'
  },
  'instance': {
    'id': 'FakeInstanceId',
    'zone': 'FakeZone'
  }
}
";
            var          platform = new Platform(GcePlatformDetails.TryLoad(json));
            var          resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("gce_instance", resource.Type);
            Assert.Equal(new Dictionary <string, string>
            {
                { "project_id", "FakeProjectId" },
                { "instance_id", "FakeInstanceId" },
                { "zone", "FakeZone" }
            }, resource.Labels);
        }
        public void GkePlatform()
        {
            const string json     = @"
{
  'project': {
    'projectId': 'FakeProjectId'
  },
  'instance': {
    'attributes': {
      'cluster-name': 'FakeClusterName',
    },
    'zone': 'projects/FakeProject/zones/FakeLocation'
  }
}
";
            var          platform = new Platform(GkePlatformDetails.TryLoad(json));
            var          resource = MonitoredResourceBuilder.FromPlatform(platform);

            Assert.Equal("gke_cluster", resource.Type);
            Assert.Equal(3, resource.Labels.Count);
            Assert.Equal("FakeProjectId", resource.Labels["project_id"]);
            Assert.Equal("FakeClusterName", resource.Labels["cluster_name"]);
            Assert.Equal("FakeLocation", resource.Labels["location"]);
        }
示例#27
0
 private ErrorReportingOptions(EventTarget eventTarget, BufferOptions bufferOptions, RetryOptions retryOptions)
     : this(GaxPreconditions.CheckNotNull(eventTarget, nameof(eventTarget)).LogName ?? LogNameDefault,
            eventTarget.MonitoredResource ?? MonitoredResourceBuilder.FromPlatform(),
            bufferOptions,
            retryOptions) =>
示例#28
0
        /// <summary>
        /// Returns <paramref name="specifiedLabel"/> if specified, otherwise attempts to resolve the <paramref name="labelKey"/>
        /// from the given, detected or cached <see cref="MonitoredResource"/> instance.
        /// </summary>
        /// <param name="specifiedLabel">The label value specified by the caller.</param>
        /// <param name="labelKey">The key of the label.</param>
        /// <param name="labelName">The friendly name of the value. Used in the exception message.</param>
        /// <param name="monitoredResource">Optional, the <see cref="MonitoredResource"/> instance.</param>
        /// <returns>The resolved value of the label.</returns>
        private static string GetAndCheckLabel(string specifiedLabel, string labelKey, string labelName, MonitoredResource monitoredResource = null)
        {
            if (specifiedLabel != null)
            {
                return(specifiedLabel);
            }

            monitoredResource = monitoredResource ?? _detectedMonitoredResource ?? (_detectedMonitoredResource = MonitoredResourceBuilder.FromPlatform());
            if (monitoredResource.Labels.TryGetValue(labelKey, out var resourceLabel))
            {
                return(resourceLabel);
            }

            throw new InvalidOperationException($"No {labelName} was passed in or detected.");
        }
示例#29
0
 private static MonitoredResource GetMonitoredResource(MonitoredResource monitoredResource) =>
 monitoredResource ?? _detectedMonitoredResource ?? (_detectedMonitoredResource = MonitoredResourceBuilder.FromPlatform());
示例#30
0
 /// <summary>
 /// Create a new instance of <see cref="LoggingOptions"/>.
 /// </summary>
 /// <param name="logLevel">Optional, the minimum log level. Defaults to <see cref="LogLevel.Information"/></param>
 /// <param name="logName">Optional, the name of the log. Defaults to 'aspnetcore'.</param>
 /// <param name="labels">Optional, custom labels to be added to log entries.
 /// Keys and values added to <paramref name="labels"/> should not be null.
 /// If they are, an exception will be thrown when attempting to log an entry.
 /// The entry won't be logged and the exception will be propagated depending
 /// on the value of <see cref="RetryOptions.ExceptionHandling"/>.</param>
 /// <param name="monitoredResource">Optional, the monitored resource. The monitored resource will
 /// be automatically detected if it is not set and will default to the global resource if the detection fails.
 /// See: https://cloud.google.com/logging/docs/api/v2/resource-list </param>
 /// <param name="bufferOptions">Optional, the buffer options. Defaults to a <see cref="BufferType.Timed"/></param>
 /// <param name="retryOptions">Optional, the retry options. Defaults to a <see cref="RetryType.None"/></param>
 public static LoggingOptions Create(LogLevel logLevel = LogLevel.Information, string logName = null,
                                     Dictionary <string, string> labels = null, MonitoredResource monitoredResource = null,
                                     BufferOptions bufferOptions        = null, RetryOptions retryOptions = null) =>
 new LoggingOptions(logLevel, logName ?? _baseLogName,
                    labels ?? new Dictionary <string, string>(), monitoredResource ?? MonitoredResourceBuilder.FromPlatform(),
                    bufferOptions ?? BufferOptions.TimedBuffer(), retryOptions ?? RetryOptions.NoRetry());