/* aplogd_io_read_data()
 *
 * Description: This function reads data from an input file descriptor and adds
 * it to the circular RAM buffer.
 *
 * @poll_num: (int) Element of the poll struct array to read from
 *
 * Return: None
 *
 * Notes: None
 */
static void aplogd_io_read_data(int poll_num)
{
	int my_fd = 0;
	int len=0;
	int ret=0;
	int ReadableLogSize;
	my_fd   = aplogd_io_fd[poll_num].fd;
	VPRINT("aplogd_io_read_data poll_num=%d.\n",poll_num);
	if(poll_num < APLOGD_INPUT_KERNEL_POLL_INDEX){
		int ret=0;
		unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4)));
		struct logger_entry *entry = (struct logger_entry *) buf;
		AndroidLogEntry log_entry;
		char binaryMsgBuf[1024];
		ReadableLogSize=ioctl(my_fd, LOGGER_GET_LOG_LEN);
		while(ReadableLogSize>0){
			ret = read (my_fd, entry, LOGGER_ENTRY_MAX_LEN);
			if (ret < 0) {
				if (errno == EINTR)
					continue;
				if (errno == EAGAIN)
					break;
				perror("logcat read");
				exit(EXIT_FAILURE);
			}
			else if (!ret) {
				EPRINT("read: Unexpected EOF!\n");
				exit(EXIT_FAILURE);
			}
			/* NOTE: driver guarantees we read exactly one full entry */
			if(entry->len >=LOGGER_ENTRY_MAX_LEN)
				entry->len=LOGGER_ENTRY_MAX_LEN-1;
			entry->msg[entry->len] = '\0';
			if(APLOGD_INPUT_EVENTS_POLL_INDEX == poll_num )
				errno = android_log_processBinaryLogBuffer(entry, &log_entry, g_eventTagMap,binaryMsgBuf, sizeof(binaryMsgBuf));
			else
				errno = android_log_processLogBuffer(entry, &log_entry);
			if(errno <0) {
				EPRINT("Error in android_log_processLogBuffer.\n");
				break;
				}
			ret=LogfilterAndBuffering(g_logformat, &log_entry, poll_num);
			if(ret<0){
				EPRINT("Error in LogfilterAndBuffering.\n");
				break;
			}else{
				unwritten_bytes+=ret;
				if(unwritten_bytes>= aplogd_output_buffering){
					aplogd_rambuf_outputall();
					unwritten_bytes=0;
					aplogd_poll_timeout=-1;
				}else{
					aplogd_poll_timeout=60000;
				}
			}
			ReadableLogSize-=ret;
		}//while loop
	}else if (APLOGD_INPUT_KERNEL_POLL_INDEX == poll_num){
static void processBuffer(log_device_t* dev, struct log_msg *buf)
{
    int bytesWritten = 0;
    int err;
    AndroidLogEntry entry;
    char binaryMsgBuf[1024];

    if (dev->binary) {
        static bool hasOpenedEventTagMap = false;
        static EventTagMap *eventTagMap = NULL;

        if (!eventTagMap && !hasOpenedEventTagMap) {
            eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
            hasOpenedEventTagMap = true;
        }
        err = android_log_processBinaryLogBuffer(&buf->entry_v1, &entry,
                                                 eventTagMap,
                                                 binaryMsgBuf,
                                                 sizeof(binaryMsgBuf));
        //printf(">>> pri=%d len=%d msg='%s'\n",
        //    entry.priority, entry.messageLen, entry.message);
    } else {
        err = android_log_processLogBuffer(&buf->entry_v1, &entry);
    }
    if (err < 0) {
        goto error;
    }

    if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) {
        bool match = regexOk(entry);

        g_printCount += match;
        if (match || g_printItAnyways) {
            bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry);

            if (bytesWritten < 0) {
                logcat_panic(false, "output error");
            }
        }
    }

    g_outByteCount += bytesWritten;

    if (g_logRotateSizeKBytes > 0
        && (g_outByteCount / 1024) >= g_logRotateSizeKBytes
    ) {
        rotateLogs();
    }

error:
    //fprintf (stderr, "Error processing record\n");
    return;
}
static void processBuffer(log_device_t* dev, struct log_msg *buf)
{
    int bytesWritten = 0;
    int err;
    AndroidLogEntry entry;
    char binaryMsgBuf[1024];

    if (dev->binary) {
        err = android_log_processBinaryLogBuffer(&buf->entry_v1, &entry,
                                                 g_eventTagMap,
                                                 binaryMsgBuf,
                                                 sizeof(binaryMsgBuf));
        //printf(">>> pri=%d len=%d msg='%s'\n",
        //    entry.priority, entry.messageLen, entry.message);
    } else {
        err = android_log_processLogBuffer(&buf->entry_v1, &entry);
    }
    if (err < 0) {
        goto error;
    }

    if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) {
        if (false && g_devCount > 1) {
            binaryMsgBuf[0] = dev->label;
            binaryMsgBuf[1] = ' ';
            bytesWritten = write(g_outFD, binaryMsgBuf, 2);
            if (bytesWritten < 0) {
                perror("output error");
                exit(-1);
            }
        }

        bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry);

        if (bytesWritten < 0) {
            perror("output error");
            exit(-1);
        }
    }

    g_outByteCount += bytesWritten;

    if (g_logRotateSizeKBytes > 0
        && (g_outByteCount / 1024) >= g_logRotateSizeKBytes
    ) {
        rotateLogs();
    }

error:
    //fprintf (stderr, "Error processing record\n");
    return;
}
Exemple #4
0
static void processBuffer(struct logger_entry *buf)
{
    int bytesWritten;
    int err;
    AndroidLogEntry entry;
    char binaryMsgBuf[1024];

    if (g_isBinary) {
        err = android_log_processBinaryLogBuffer(buf, &entry, g_eventTagMap,
                binaryMsgBuf, sizeof(binaryMsgBuf));
        //printf(">>> pri=%d len=%d msg='%s'\n",
        //    entry.priority, entry.messageLen, entry.message);
    } else {
        err = android_log_processLogBuffer(buf, &entry);
    }
    if (err < 0)
        goto error;

    bytesWritten = android_log_filterAndPrintLogLine(
                        g_logformat, g_outFD, &entry);

    if (bytesWritten < 0) {
        perror("output error");
        exit(-1);
    }

    g_outByteCount += bytesWritten;

    if (g_logRotateSizeKBytes > 0 
        && (g_outByteCount / 1024) >= g_logRotateSizeKBytes
    ) {
        rotateLogs();
    }

error:
    //fprintf (stderr, "Error processing record\n");
    return;
}
status_t LogSection::BlockingCall(int pipeWriteFd) const {
    // Open log buffer and getting logs since last retrieved time if any.
    unique_ptr<logger_list, void (*)(logger_list*)> loggers(
            gLastLogsRetrieved.find(mLogID) == gLastLogsRetrieved.end()
                    ? android_logger_list_alloc(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, 0)
                    : android_logger_list_alloc_time(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
                                                     gLastLogsRetrieved[mLogID], 0),
            android_logger_list_free);

    if (android_logger_open(loggers.get(), mLogID) == NULL) {
        ALOGE("LogSection %s: Can't get logger.", this->name.string());
        return -1;
    }

    log_msg msg;
    log_time lastTimestamp(0);

    ProtoOutputStream proto;
    while (true) {  // keeps reading until logd buffer is fully read.
        status_t err = android_logger_list_read(loggers.get(), &msg);
        // err = 0 - no content, unexpected connection drop or EOF.
        // err = +ive number - size of retrieved data from logger
        // err = -ive number, OS supplied error _except_ for -EAGAIN
        // err = -EAGAIN, graceful indication for ANDRODI_LOG_NONBLOCK that this is the end of data.
        if (err <= 0) {
            if (err != -EAGAIN) {
                ALOGW("LogSection %s: fails to read a log_msg.\n", this->name.string());
            }
            // dump previous logs and don't consider this error a failure.
            break;
        }
        if (mBinary) {
            // remove the first uint32 which is tag's index in event log tags
            android_log_context context = create_android_log_parser(msg.msg() + sizeof(uint32_t),
                                                                    msg.len() - sizeof(uint32_t));
            ;
            android_log_list_element elem;

            lastTimestamp.tv_sec = msg.entry_v1.sec;
            lastTimestamp.tv_nsec = msg.entry_v1.nsec;

            // format a BinaryLogEntry
            uint64_t token = proto.start(LogProto::BINARY_LOGS);
            proto.write(BinaryLogEntry::SEC, msg.entry_v1.sec);
            proto.write(BinaryLogEntry::NANOSEC, msg.entry_v1.nsec);
            proto.write(BinaryLogEntry::UID, (int)msg.entry_v4.uid);
            proto.write(BinaryLogEntry::PID, msg.entry_v1.pid);
            proto.write(BinaryLogEntry::TID, msg.entry_v1.tid);
            proto.write(BinaryLogEntry::TAG_INDEX,
                        get4LE(reinterpret_cast<uint8_t const*>(msg.msg())));
            do {
                elem = android_log_read_next(context);
                uint64_t elemToken = proto.start(BinaryLogEntry::ELEMS);
                switch (elem.type) {
                    case EVENT_TYPE_INT:
                        proto.write(BinaryLogEntry::Elem::TYPE,
                                    BinaryLogEntry::Elem::EVENT_TYPE_INT);
                        proto.write(BinaryLogEntry::Elem::VAL_INT32, (int)elem.data.int32);
                        break;
                    case EVENT_TYPE_LONG:
                        proto.write(BinaryLogEntry::Elem::TYPE,
                                    BinaryLogEntry::Elem::EVENT_TYPE_LONG);
                        proto.write(BinaryLogEntry::Elem::VAL_INT64, (long long)elem.data.int64);
                        break;
                    case EVENT_TYPE_STRING:
                        proto.write(BinaryLogEntry::Elem::TYPE,
                                    BinaryLogEntry::Elem::EVENT_TYPE_STRING);
                        proto.write(BinaryLogEntry::Elem::VAL_STRING, elem.data.string, elem.len);
                        break;
                    case EVENT_TYPE_FLOAT:
                        proto.write(BinaryLogEntry::Elem::TYPE,
                                    BinaryLogEntry::Elem::EVENT_TYPE_FLOAT);
                        proto.write(BinaryLogEntry::Elem::VAL_FLOAT, elem.data.float32);
                        break;
                    case EVENT_TYPE_LIST:
                        proto.write(BinaryLogEntry::Elem::TYPE,
                                    BinaryLogEntry::Elem::EVENT_TYPE_LIST);
                        break;
                    case EVENT_TYPE_LIST_STOP:
                        proto.write(BinaryLogEntry::Elem::TYPE,
                                    BinaryLogEntry::Elem::EVENT_TYPE_LIST_STOP);
                        break;
                    case EVENT_TYPE_UNKNOWN:
                        proto.write(BinaryLogEntry::Elem::TYPE,
                                    BinaryLogEntry::Elem::EVENT_TYPE_UNKNOWN);
                        break;
                }
                proto.end(elemToken);
            } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
            proto.end(token);
            if (context) {
                android_log_destroy(&context);
            }
        } else {
            AndroidLogEntry entry;
            err = android_log_processLogBuffer(&msg.entry_v1, &entry);
            if (err != NO_ERROR) {
                ALOGW("LogSection %s: fails to process to an entry.\n", this->name.string());
                break;
            }
            lastTimestamp.tv_sec = entry.tv_sec;
            lastTimestamp.tv_nsec = entry.tv_nsec;

            // format a TextLogEntry
            uint64_t token = proto.start(LogProto::TEXT_LOGS);
            proto.write(TextLogEntry::SEC, (long long)entry.tv_sec);
            proto.write(TextLogEntry::NANOSEC, (long long)entry.tv_nsec);
            proto.write(TextLogEntry::PRIORITY, (int)entry.priority);
            proto.write(TextLogEntry::UID, entry.uid);
            proto.write(TextLogEntry::PID, entry.pid);
            proto.write(TextLogEntry::TID, entry.tid);
            proto.write(TextLogEntry::TAG, entry.tag, trimTail(entry.tag, entry.tagLen));
            proto.write(TextLogEntry::LOG, entry.message,
                        trimTail(entry.message, entry.messageLen));
            proto.end(token);
        }
    }
    gLastLogsRetrieved[mLogID] = lastTimestamp;
    if (!proto.flush(pipeWriteFd) && errno == EPIPE) {
        ALOGE("[%s] wrote to a broken pipe\n", this->name.string());
        return EPIPE;
    }
    return NO_ERROR;
}