log.cpp revision f86b5a6b90619e02d1d034ef7b0adc3b439f4abb
1da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes/* 2da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * Copyright (C) 2015 The Android Open Source Project 3da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * 4da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * you may not use this file except in compliance with the License. 6da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * You may obtain a copy of the License at 7da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * 8da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * 10da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * See the License for the specific language governing permissions and 14da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes * limitations under the License. 15da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes */ 16da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes 17e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes#include "log.h" 18e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes 19da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <stdlib.h> 20da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <string.h> 21da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <sys/uio.h> 22da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes 23da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <selinux/selinux.h> 24da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes 25f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughesstatic const int kLogSeverityToKLogLevel[] = { 26f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes KLOG_NOTICE_LEVEL, KLOG_DEBUG_LEVEL, KLOG_INFO_LEVEL, 27f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes KLOG_WARNING_LEVEL, KLOG_ERROR_LEVEL, KLOG_ERROR_LEVEL, 28f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes}; 29f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughesstatic_assert(arraysize(kLogSeverityToKLogLevel) == android::base::FATAL + 1, 30f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes "Mismatch in size of kLogSeverityToKLogLevel and values in LogSeverity"); 31da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes 32f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughesstatic void KernelLogger(android::base::LogId, android::base::LogSeverity severity, 33f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes const char* tag, const char*, unsigned int, const char* msg) { 34f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes int level = kLogSeverityToKLogLevel[severity]; 355db8d6aafa66cbeaef6bf736ff5ad5b711069d9eNick Kralevich if (level > klog_get_level()) return; 365db8d6aafa66cbeaef6bf736ff5ad5b711069d9eNick Kralevich 37e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes // The kernel's printk buffer is only 1024 bytes. 38e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes // TODO: should we automatically break up long lines into multiple lines? 39e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes // Or we could log but with something like "..." at the end? 40e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes char buf[1024]; 41f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes size_t size = snprintf(buf, sizeof(buf), "<%d>%s: %s\n", level, tag, msg); 42f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes if (size > sizeof(buf)) { 43f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes size = snprintf(buf, sizeof(buf), "<%d>%s: %zu-byte message too long for printk\n", 44f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes level, tag, size); 45e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes } 46da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes 47e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes iovec iov[1]; 48e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes iov[0].iov_base = buf; 49f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes iov[0].iov_len = size; 50e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes klog_writev(level, iov, 1); 51da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes} 52da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes 53f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughesvoid InitKernelLogging(char* argv[]) { 54f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes android::base::InitLogging(argv, &KernelLogger); 55f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes 56f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes klog_init(); 57f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes klog_set_level(KLOG_NOTICE_LEVEL); 58da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes} 59da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes 60da40c00137f75543a69972f1be506e2d14a41845Elliott Hughesint selinux_klog_callback(int type, const char *fmt, ...) { 61f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes android::base::LogSeverity severity = android::base::ERROR; 62da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes if (type == SELINUX_WARNING) { 63f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes severity = android::base::WARNING; 64da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes } else if (type == SELINUX_INFO) { 65f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes severity = android::base::INFO; 66da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes } 67f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes char buf[1024]; 68da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes va_list ap; 69da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes va_start(ap, fmt); 70f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes vsnprintf(buf, sizeof(buf), fmt, ap); 71da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes va_end(ap); 72f86b5a6b90619e02d1d034ef7b0adc3b439f4abbElliott Hughes KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf); 73da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes return 0; 74da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes} 75