func parseLsnrctlStatusOutput()

in internal/oraclediscovery/oraclediscovery.go [393:462]


func parseLsnrctlStatusOutput(ctx context.Context, r io.Reader, envVars map[string]string) (*odpb.Discovery_Listener, error) {
	scanner := bufio.NewScanner(r)
	listener := &odpb.Discovery_Listener{}
	currentServiceName := ""

	reAlias := regexp.MustCompile(`Alias\s+(.*)`)
	reTraceLevel := regexp.MustCompile(`Trace Level\s+(.*)`)
	reSecurity := regexp.MustCompile(`Security\s+(.*)`)
	reStartDate := regexp.MustCompile(`Start Date\s+(\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2})`)
	reParameterFile := regexp.MustCompile(`Listener Parameter File\s+(.*)`)
	reLogFile := regexp.MustCompile(`Listener Log File\s+(.*)`)
	reService := regexp.MustCompile(`Service\s+"([^"]+)"\s+has\s+\d+\s+instance\(s\)`)
	reInstance := regexp.MustCompile(`Instance\s+"([^"]+)",\s+status\s+(\w+),`)
	reEndpoint := regexp.MustCompile(`\s*\(DESCRIPTION=\(ADDRESS=`)

	for scanner.Scan() {
		line := scanner.Text()

		switch {
		case reAlias.MatchString(line):
			alias := reAlias.FindStringSubmatch(line)[1]
			listener.Id = &odpb.Discovery_Listener_ListenerId{
				Alias:      alias,
				OracleHome: envVars["ORACLE_HOME"],
			}
		case reStartDate.MatchString(line):
			startDateStr := reStartDate.FindStringSubmatch(line)[1]
			startDate, err := time.Parse("02-Jan-2006 15:04:05", startDateStr)
			if err != nil {
				log.CtxLogger(ctx).Warnw("Failed to parse start date", "error", err, "date_string", startDateStr)
			}
			listener.StartTime = timestamppb.New(startDate)
		case reSecurity.MatchString(line):
			listener.Security = reSecurity.FindStringSubmatch(line)[1]
		case reParameterFile.MatchString(line):
			listener.ParameterFile = reParameterFile.FindStringSubmatch(line)[1]
		case reLogFile.MatchString(line):
			listener.LogFile = reLogFile.FindStringSubmatch(line)[1]
		case reTraceLevel.MatchString(line):
			listener.TraceLevel = reTraceLevel.FindStringSubmatch(line)[1]
		case reService.MatchString(line):
			currentServiceName = reService.FindStringSubmatch(line)[1]
			service := &odpb.Discovery_Listener_Service{
				Name: currentServiceName,
			}
			listener.Services = append(listener.Services, service)
		case reInstance.MatchString(line) && currentServiceName != "":
			matches := reInstance.FindStringSubmatch(line)
			instance := &odpb.Discovery_Listener_Service_DatabaseInstance{
				Name:   matches[1],
				Status: matches[2],
			}
			if len(listener.Services) > 0 {
				lastService := listener.Services[len(listener.Services)-1]
				lastService.Instances = append(lastService.Instances, instance)
			}
		case reEndpoint.MatchString(line):
			listener.Endpoints = append(listener.Endpoints, parseListenerEndpoint(ctx, line))
		}
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}

	if listener.Id == nil {
		return nil, errIncompleteData
	}

	return listener, nil
}