static void program_scheduler_handle_error(ProgramScheduler *program_scheduler,
                                           bool log_as_error, const char *format, ...) {
	va_list arguments;
	char buffer[1024];
	Program *program = containerof(program_scheduler, Program, scheduler);
	String *message;

	va_start(arguments, format);

	vsnprintf(buffer, sizeof(buffer), format, arguments);

	va_end(arguments);

	if (log_as_error) {
		log_error("Scheduler error for program object (identifier: %s) occurred: %s",
		          program->identifier->buffer, buffer);
	} else {
		log_debug("Scheduler error for program object (identifier: %s) occurred: %s",
		          program->identifier->buffer, buffer);
	}

	if (string_wrap(buffer, NULL,
	                OBJECT_CREATE_FLAG_INTERNAL |
	                OBJECT_CREATE_FLAG_LOCKED,
	                NULL, &message) != API_E_SUCCESS) {
		message = NULL;
	}

	program_scheduler_stop(program_scheduler, message);
}
Esempio n. 2
0
APIE inventory_get_stock_string(const char *buffer, String **string) {
	int i;
	String *candidate;
	APIE error_code;
	String **string_ptr;

	for (i = 0; i < _stock_strings.count; ++i) {
		candidate = *(String **)array_get(&_stock_strings, i);

		if (strcmp(candidate->buffer, buffer) == 0) {
			string_acquire_and_lock(candidate);

			*string = candidate;

			return API_E_SUCCESS;
		}
	}

	error_code = string_wrap(buffer, NULL,
	                         OBJECT_CREATE_FLAG_INTERNAL |
	                         OBJECT_CREATE_FLAG_LOCKED,
	                         NULL, string);

	if (error_code != API_E_SUCCESS) {
		return error_code;
	}

	string_ptr = array_append(&_stock_strings);

	if (string_ptr == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to stock string array: %s (%d)",
		          get_errno_name(errno), errno);

		string_unlock_and_release(*string);

		return error_code;
	}

	*string_ptr = *string;

	string_acquire_and_lock(*string);

	return API_E_SUCCESS;
}
static File *program_scheduler_prepare_continuous_log(ProgramScheduler *program_scheduler,
                                                      struct timeval timestamp,
                                                      const char *suffix) {
	struct tm localized_timestamp;
	char iso8601dt[64] = "unknown";
	char iso8601usec[16] = "";
	char iso8601tz[16] = "";
	char buffer[1024];
	APIE error_code;
	String *name;
	File *file;

	// format ISO 8601 date, time and timezone offset
	if (localtime_r(&timestamp.tv_sec, &localized_timestamp) != NULL) {
		// can use common ISO 8601 format YYYY-MM-DDThh:mm:ss.uuuuuu±hhmm
		// because this timestamp is not part of a filename
		strftime(iso8601dt, sizeof(iso8601dt), "%Y-%m-%dT%H:%M:%S", &localized_timestamp);
		snprintf(iso8601usec, sizeof(iso8601usec), ".%06d", (int)timestamp.tv_usec);
		strftime(iso8601tz, sizeof(iso8601tz), "%z", &localized_timestamp);
	}

	// format log filename
	if (robust_snprintf(buffer, sizeof(buffer), "%s/continuous_%s.log",
	                    program_scheduler->log_directory, suffix) < 0) {
		program_scheduler_handle_error(program_scheduler, true,
		                               "Could not format %s log file name: %s (%d)",
		                               suffix, get_errno_name(errno), errno);

		return NULL;
	}

	error_code = string_wrap(buffer, NULL,
	                         OBJECT_CREATE_FLAG_INTERNAL |
	                         OBJECT_CREATE_FLAG_LOCKED,
	                         NULL, &name);

	if (error_code != API_E_SUCCESS) {
		program_scheduler_handle_error(program_scheduler, true,
		                               "Could not wrap %s log file name into string object: %s (%d)",
		                               suffix, api_get_error_code_name(error_code), error_code);

		return NULL;
	}

	// open log file
	error_code = file_open(name->base.id,
	                       FILE_FLAG_WRITE_ONLY | FILE_FLAG_CREATE | FILE_FLAG_APPEND,
	                       0644, 1000, 1000,
	                       NULL, OBJECT_CREATE_FLAG_INTERNAL, NULL, &file);

	string_unlock_and_release(name);

	if (error_code != API_E_SUCCESS) {
		program_scheduler_handle_error(program_scheduler, true,
		                               "Could not open/create %s log file: %s (%d)",
		                               suffix, api_get_error_code_name(error_code), error_code);

		return NULL;
	}

	// format header
	if (robust_snprintf(buffer, sizeof(buffer), "\n\n%s%s%s\n-------------------------------------------------------------------------------\n",
	                    iso8601dt, iso8601usec, iso8601tz) < 0) {
		program_scheduler_handle_error(program_scheduler, true,
		                               "Could not format timestamp for %s log file: %s (%d)",
		                               suffix, get_errno_name(errno), errno);

		file_release(file);

		return NULL;
	}

	// write header
	if (write(file->fd, buffer, strlen(buffer)) < 0) {
		program_scheduler_handle_error(program_scheduler, true,
		                               "Could not write timestamp to %s log file: %s (%d)",
		                               suffix, get_errno_name(errno), errno);

		file_release(file);

		return NULL;
	}

	return file;
}
static File *program_scheduler_prepare_individual_log(ProgramScheduler *program_scheduler,
                                                      struct timeval timestamp,
                                                      const char *suffix) {
	uint64_t microseconds = (uint64_t)timestamp.tv_sec * 1000000 + (uint64_t)timestamp.tv_usec;
	struct tm localized_timestamp;
	char iso8601[128] = "unknown";
	char buffer[1024];
	struct stat st;
	APIE error_code;
	int counter = 0;
	String *name;
	File *file;

	// format ISO 8601 date, time and timezone offset
	if (localtime_r(&timestamp.tv_sec, &localized_timestamp) != NULL) {
		// use ISO 8601 format YYYYMMDDThhmmss±hhmm instead of the common
		// YYYY-MM-DDThh:mm:ss±hhmm because the colons in there can create
		// problems on Windows which does not allow colons in filenames
		strftime(iso8601, sizeof(iso8601), "%Y%m%dT%H%M%S%z", &localized_timestamp);
	}

	// create log file, include microsecond timestamp to reduce the chance for
	// file name collisions and as easy-to-parse timestamp for brickv
	if (robust_snprintf(buffer, sizeof(buffer), "%s/%s_%"PRIu64"_%s.log",
	                    program_scheduler->log_directory,
	                    iso8601, microseconds, suffix) < 0) {
		program_scheduler_handle_error(program_scheduler, true,
		                               "Could not format %s log file name: %s (%d)",
		                               suffix, get_errno_name(errno), errno);

		return NULL;
	}

	while (counter < 1000) {
		// only try to create the log file if it's not already existing
		if (lstat(buffer, &st) < 0) {
			error_code = string_wrap(buffer, NULL,
			                         OBJECT_CREATE_FLAG_INTERNAL |
			                         OBJECT_CREATE_FLAG_LOCKED,
			                         NULL, &name);

			if (error_code != API_E_SUCCESS) {
				program_scheduler_handle_error(program_scheduler, true,
				                               "Could not wrap %s log file name into string object: %s (%d)",
				                               suffix, api_get_error_code_name(error_code), error_code);

				return NULL;
			}

			error_code = file_open(name->base.id,
			                       FILE_FLAG_WRITE_ONLY | FILE_FLAG_CREATE | FILE_FLAG_EXCLUSIVE,
			                       0644, 1000, 1000,
			                       NULL, OBJECT_CREATE_FLAG_INTERNAL, NULL, &file);

			string_unlock_and_release(name);

			if (error_code == API_E_SUCCESS) {
				return file;
			}

			// if file_open failed with an error different from API_E_ALREADY_EXISTS
			// then give up, there is no point trying to recover this situation
			if (error_code != API_E_ALREADY_EXISTS) {
				program_scheduler_handle_error(program_scheduler, true,
				                               "Could not create %s log file: %s (%d)",
				                               suffix, api_get_error_code_name(error_code), error_code);

				return NULL;
			}
		}

		if (robust_snprintf(buffer, sizeof(buffer), "%s/%s_%"PRIu64"+%03d_%s.log",
		                    program_scheduler->log_directory,
		                    iso8601, microseconds, ++counter, suffix) < 0) {
			program_scheduler_handle_error(program_scheduler, true,
			                               "Could not format %s log file name: %s (%d)",
			                               suffix, get_errno_name(errno), errno);

			return NULL;
		}
	}

	program_scheduler_handle_error(program_scheduler, true,
	                               "Could not create %s log file within 1000 attempts",
	                               suffix);

	return NULL;
}
Esempio n. 5
0
/** Sets the item's message text. */
void
LogTreeItem::setMessage(const QString &message)
{
  setText(COL_MESG, message);
  setToolTip(COL_MESG, string_wrap(message, 80, " ", "\r\n"));
}